Routing maps an incoming HTTP request to the handler that produces its response. A single handler can serve a small application, but separate handlers make distinct paths and HTTP methods easier to manage as a server grows. In Go, net/http supplies the standard starting point. section 2.3 section 2.3.3
Choose a pattern according to what distinguishes the requests:
- For a few fixed paths, register a handler for each path with http.HandleFunc or a ServeMux. A trailing-slash pattern can also cover paths beneath it; the handler may then need to inspect the remaining path. section 2.3.3
- For one path with different operations, include the HTTP method in the pattern, such as GET /comments and POST /comments. A wrapper handler can inspect request attributes when registration patterns do not provide enough control. section 8.1.1
- For an identifier in the URL, register a variable pattern such as GET /comments/{id}, read it with r.PathValue("id"), and validate it before using it. section 8.2
- For separate areas of an application, mount ServeMux instances beneath path prefixes. More elaborate matching can instead use a custom regular-expression resolver; consider that added machinery only when simpler patterns do not fit. section 8.2 section 2.3.3
One endpoint, two methods, one path value
A comments API can send GET /comments to a list handler and POST /comments to a creation handler. Register GET /comments/{id} separately for an individual comment. That handler reads r.PathValue("id"), converts it to a number, and returns a not-found response when the requested comment does not exist. The method and path together determine which handler runs; the variable supplies data to that handler. section 8.1.1 section 8.2
Listing 8.7 Extracting information from request path
func getComment(w http.ResponseWriter, r *http.Request) {
commentID, err := strconv.Atoi(r.PathValue("id")) #1
if err != nil { #2
w.WriteHeader(http.StatusInternalServerError)
return
}
if commentID == 0 || len(comments) < commentID { #3
w.WriteHeader(http.StatusNotFound)
return
}
fmt.Fprintf(w, "Comment %d: %s", commentID,
comments[commentID-1].text) #4
}
func main() {
http.HandleFunc("GET /comments", getComments)
http.HandleFunc("GET /comments/{id}", getComment) #5
http.HandleFunc("POST /comments", postComments)
if err := http.ListenAndServe(":8000", nil); err != nil {
panic(err)
}
}
The handler registration and r.PathValue("id") call show how a variable path pattern reaches a specific comment handler. section 8.2





















