Go 1.22 brings two enhancements to the net/http package’s router: method matching and wildcards. These features let you express common routes as patterns instead of Go code. Although they are simple to explain and use, it was a challenge to come up with the right rules for selecting the winning pattern when several match a request.
Go 1.22 added new features to their net/http package to make it a good alternative to using third-party libraries. In this article, we will look at how to handle routing using Golang's net/http package. We will start with the basic route handling and then move on to grouping those routes.
Notes
Let us start by looking at how to register your routes.
// main.go package main import ( "log" "net/http" ) func main() { router := http.NewServeMux() router.HandleFunc("GET /users/", getUsers) router.HandleFunc("POST /users/", createUser) router.HandleFunc("GET /users/{id}/", getUser) router.HandleFunc("DELETE /users/{id}/", deleteUser) err := http.ListenAndServe(":8000", router) if err != nil { log.Fatal(err) } } // Here goes the implementation for getUsers, getUser, createUser, deleteUser // Check the repo in services/users/routes.go type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` } var users []User = []User{ {ID: 1, Name: "Bumblebee", Email: "bumblebee@autobots.com"}, {ID: 2, Name: "Optimus Prime", Email: "optimus.prime@autobots.com"}, {ID: 3, Name: "Ironhide", Email: "ironhide@autobots.com"}, {ID: 4, Name: "Hot Rod", Email: "hot.rod@autobots.com"}, } func getUsers(w http.ResponseWriter, r *http.Request) { response := map[string]any{ "message": "Done", "users": users, } utils.WriteJSONResponse(w, http.StatusOK, response) }
Let's go through the above code:
Note: When making requests make sure to add the trailing slash. Doing otherwise will return a 404 not found response
Example:
Sample Request:
// statusCode: 200 { "message": "Done", "users": [ { "id": 1, "name": "Bumblebee", "email": "bumblebee@autobots.com" }, { "id": 2, "name": "Optimus Prime", "email": "optimus.prime@autobots.com" }, { "id": 3, "name": "Ironhide", "email": "ironhide@autobots.com" }, { "id": 4, "name": "Hot Rod", "email": "hot.rod@autobots.com" } ] }
As we can see from the above, this would require us to register all endpoints in the same place and can get out of hand quickly. Grouping routes helps you keep your code organized, scalable, and maintainable by putting related routes and logic together. It allows you to apply middleware selectively, encourages reusability, and improves readability, especially as your application grows.
Now let us look at how we can group routes
We will start by registering routes locally in the package where their handler functions are defined. The next step is to bring all those various routes together and start the server.
// services/users/routes.go package user import ( "fmt" "net/http" "strconv" "<your-project-name>/gorouting/utils" ) type Handler struct{} func NewHandler() *Handler { return &Handler{} } func (h *Handler) RegisterRoutes() *http.ServeMux { r := http.NewServeMux() r.HandleFunc("GET /", getUsers) r.HandleFunc("POST /", createUser) r.HandleFunc("GET /{id}/", getUser) r.HandleFunc("DELETE /{id}/", deleteUser) return r } // ...
Let's go through the code.
// main.go package main import ( "log" "net/http" ) func main() { router := http.NewServeMux() router.HandleFunc("GET /users/", getUsers) router.HandleFunc("POST /users/", createUser) router.HandleFunc("GET /users/{id}/", getUser) router.HandleFunc("DELETE /users/{id}/", deleteUser) err := http.ListenAndServe(":8000", router) if err != nil { log.Fatal(err) } } // Here goes the implementation for getUsers, getUser, createUser, deleteUser // Check the repo in services/users/routes.go type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` } var users []User = []User{ {ID: 1, Name: "Bumblebee", Email: "bumblebee@autobots.com"}, {ID: 2, Name: "Optimus Prime", Email: "optimus.prime@autobots.com"}, {ID: 3, Name: "Ironhide", Email: "ironhide@autobots.com"}, {ID: 4, Name: "Hot Rod", Email: "hot.rod@autobots.com"}, } func getUsers(w http.ResponseWriter, r *http.Request) { response := map[string]any{ "message": "Done", "users": users, } utils.WriteJSONResponse(w, http.StatusOK, response) }
Here we are going to focus on the Run method.
// statusCode: 200 { "message": "Done", "users": [ { "id": 1, "name": "Bumblebee", "email": "bumblebee@autobots.com" }, { "id": 2, "name": "Optimus Prime", "email": "optimus.prime@autobots.com" }, { "id": 3, "name": "Ironhide", "email": "ironhide@autobots.com" }, { "id": 4, "name": "Hot Rod", "email": "hot.rod@autobots.com" } ] }
“With Go 1.22, net/http is now more versatile, offering route patterns that improve clarity and efficiency. This approach to grouping routes shows how easy it is to maintain scalable code while taking advantage of Go’s built-in routing capabilities.” ChatGPT
Now that we have managed to group the user routes. Clone the repo and try adding another service.
The above is the detailed content of Go Routing : Handling and Grouping Routes with net/http. For more information, please follow other related articles on the PHP Chinese website!