Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
•
KI & AI VideosJulian Goldie SEO: Claude Sonnet 5.5 is HERE!(29.09.2026 um 11:33 Uhr)
•
KI & AI VideosJulian Goldie SEO: Claude Sonnet 5.5 is HERE! 📱(29.09.2026 um 11:41 Uhr)
••
IT Security ToolsIPA(29.09.2026 um 10:41 Uhr)
•
Sicherheitslücken (CVE)Apple patches CoreGraphics flaw linked to targeted iPhone attacks(29.09.2026 um 11:23 Uhr)
•
Malware / Trojaner / VirenSilverFox Built Fake Software Sites That Know When Researchers Are Watching(29.09.2026 um 11:46 Uhr)
•••••
KI & AI VideosJulian Goldie SEO: Claude Sonnet 5.5 is HERE!(29.09.2026 um 11:33 Uhr)
•
KI & AI VideosJulian Goldie SEO: Claude Sonnet 5.5 is HERE! 📱(29.09.2026 um 11:41 Uhr)
••
IT Security ToolsIPA(29.09.2026 um 10:41 Uhr)
•
Sicherheitslücken (CVE)Apple patches CoreGraphics flaw linked to targeted iPhone attacks(29.09.2026 um 11:23 Uhr)
•
Malware / Trojaner / VirenSilverFox Built Fake Software Sites That Know When Researchers Are Watching(29.09.2026 um 11:46 Uhr)
••••
Intelligence View
⚡ tsecurity.de Intelligence

Building Web Servers from First Principles (Part 5)

In Chapter 4, we built dynamic routing that could handle URL parameters like /users/:id. But real APIs need more than just path parameters - they need to handle query parameters for filtering, pagination, and user input. Today, we'll…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

In Chapter 4, we built dynamic routing that could handle URL parameters like /users/:id. But real APIs need more than just path parameters - they need to handle query parameters for filtering, pagination, and user input.



Today, we'll learn how to work with query parameters to build more interactive APIs.






What We've Built So Far



From previous chapters:




  • ✅ Dynamic routing with URL parameters (/users/:id)

  • ✅ Parameter extraction and access

  • ✅ Basic JSON responses

  • ❌ Query parameter handling (?name=John&age=25)

  • ❌ Parameter validation and type conversion






Understanding Query Parameters



When frontend developers make requests like these:




// Search with query parameters
fetch('/search?q=javascript&page=2')

// Greeting with optional name
fetch('/greet?name=John')

// Math operations with parameters
fetch('/math/add?a=10&b=20')






The server needs to extract and use those query parameters. Unlike URL parameters (:id), query parameters come after the ? and are passed as key-value pairs.






Simple Query Parameter Extraction



Let's start with a basic greeting handler that uses query parameters. Update main.go:




package main

import (
"fmt"
"net/http"
)

func main() {
server := NewServer(":3000")
setupRoutes(server)

server.Start()
}

func setupRoutes(s *Server) {
s.Router.GET("/greet", greet)
}

func greet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")

name := r.URL.Query().Get("name")

if name == "" {
w.Write([]byte("Hello stranger!"))
return
}

w.Write([]byte(fmt.Sprintf("Hello %s", name)))
}






How Query Parameter Access Works:





  • r.URL.Query() returns all query parameters as a url.Values type


  • Get("name") extracts the value for the name parameter

  • If the parameter doesn't exist, Get() returns an empty string



Test this handler:




go run .









curl "http://localhost:3000/greet"
# Returns: Hello stranger!

curl "http://localhost:3000/greet?name=John"
# Returns: Hello John

curl "http://localhost:3000/greet?name=Jane%20Doe"
# Returns: Hello Jane Doe






Notice how URL encoding works - %20 becomes a space.






Multiple Query Parameters



Real APIs often need multiple parameters. Let's create a search handler:




func setupRoutes(s *Server) {
s.Router.GET("/greet", greet)
s.Router.GET("/search", search)
}

func search(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")

query := r.URL.Query().Get("q")
page := r.URL.Query().Get("page")

w.Write([]byte(fmt.Sprintf("Search results for '%s' (page %s)", query, page)))
}






Test with multiple parameters:




curl "http://localhost:3000/search?q=golang"
# Returns: Search results for 'golang' (page )

curl "http://localhost:3000/search?q=golang&page=3"
# Returns: Search results for 'golang' (page 3)

curl "http://localhost:3000/search?page=2&q=web%20development"
# Returns: Search results for 'web development' (page 2)






Key Insights:




  • Parameter order in the URL doesn't matter

  • Missing parameters return empty strings

  • Empty parameters show as blank in the output






Parameter Type Conversion



Often you need to convert query parameters to specific types and validate them. Let's create a math handler:




func setupRoutes(s *Server) {
s.Router.GET("/greet", greet)
s.Router.GET("/search", search)
s.Router.GET("/math/add", add)
}

func add(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")

a, _ := strconv.ParseInt(r.URL.Query().Get("a"), 0, 0)
b, _ := strconv.ParseInt(r.URL.Query().Get("b"), 0, 0)

w.Write([]byte(fmt.Sprintf("%d + %d = %d", a, b, a+b)))
}






Test the math handler with different inputs:




curl "http://localhost:3000/math/add?a=10&b=20"
# Returns: 10 + 20 = 30

curl "http://localhost:3000/math/add?a=100&b=-50"
# Returns: 100 + -50 = 50

curl "http://localhost:3000/math/add?a=hello&b=20"
# Returns: 0 + 20 = 20

curl "http://localhost:3000/math/add?a=10"
# Returns: 10 + 0 = 10









Understanding Different Parameter Types



Let's break down the different ways clients can send data to your API:






1. URL Parameters (Path Parameters)






/users/123        → :id = "123"
/api/v1/users/456 → :version = "v1", :id = "456"







  • Part of the URL path

  • Required (URL won't match without them)

  • Extracted using our GetPathValue() function






2. Query Parameters






/search?q=golang&page=2 → q = "golang", page = "2"







  • After the ? in the URL

  • Optional (URL still matches if missing)

  • Extracted using r.URL.Query().Get()






3. Combined Usage






/users/123/posts?limit=10&sort=date








  • :id from path = "123"


  • limit from query = "10"


  • sort from query = "date"






Common Query Parameter Patterns






Pattern 1: Optional Parameters with Defaults






func listUsers(w http.ResponseWriter, r *http.Request) {
// Get parameters with defaults
limitStr := r.URL.Query().Get("limit")
if limitStr == "" {
limitStr = "10" // Default limit
}

sortBy := r.URL.Query().Get("sort")
if sortBy == "" {
sortBy = "name" // Default sort
}

// Use the parameters...
}









Pattern 2: Boolean Parameters






func listProducts(w http.ResponseWriter, r *http.Request) {
// Boolean parameters
inStock := r.URL.Query().Get("in_stock") == "true"
onSale := r.URL.Query().Get("on_sale") == "true"

// Use boolean flags...
}









Pattern 3: Multiple Values for Same Parameter






func filterData(w http.ResponseWriter, r *http.Request) {
// Get all values for a parameter
tags := r.URL.Query()["tags"] // []string
categories := r.URL.Query()["category"] // []string

// Handle multiple values...
}






Test URL: /filter?tags=web&tags=api&category=tutorial&category=golang






Comparing Our Approach to Frameworks






Our Approach:






func handler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
id := GetPathValue(r, "id")
}









Gin Framework:






func handler(c *gin.Context) {
name := c.Query("name")
id := c.Param("id")
}









Echo Framework:






func handler(c echo.Context) error {
name := c.QueryParam("name")
id := c.Param("id")
}






The concepts are identical - frameworks just provide convenience methods!






Current Implementation



Our handlers demonstrate basic query parameter handling with different patterns:




  • Simple parameter extraction with r.URL.Query().Get()

  • Multiple parameters in a single handler

  • Type conversion using strconv.ParseInt()






Testing All Our Handlers



Let's test our complete handler collection:




# Test greeting handler
curl "http://localhost:3000/greet?name=Alice"

# Test search handler
curl "http://localhost:3000/search?q=golang%20tutorial&page=1"

# Test math handler
curl "http://localhost:3000/math/add?a=15&b=25"

# Test with invalid numbers (they become 0)
curl "http://localhost:3000/math/add?a=not_a_number&b=10"









What We've Accomplished



We now have:




  • ✅ Query parameter extraction (r.URL.Query().Get())

  • ✅ Multiple parameter handling (search with query + page)

  • ✅ Type conversion (strings to integers with strconv.ParseInt())

  • ✅ Basic math operations with URL parameters






What's Next?



In Chapter 6, we'll expand our server capabilities:





  • Data Persistence: Working with structured data storage


  • JSON APIs: Creating proper JSON request/response handling


  • Request Body Processing: Handling POST/PUT requests with JSON data


  • CRUD Operations: Building a complete API for managing resources






Challenge: Try creating a /calculator endpoint that accepts operation (add, subtract, multiply, divide), a, and b parameters. Handle division by zero and invalid operations!



Bonus: Add support for multiple values: /tags?name=web&name=api&name=tutorial and return all tag names.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Building Web Servers from First Principles (Part 5)

Thematisch verwandte Begriffe: Building, Servers, from, First · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-102241 | A vulnerability was determined in Netcore NAP930 0.1.241010.141410. Thi…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag