Routing (using gorilla/mux)
The built-in package net/http
has a simple default router, but it may not cover more advanced routing scenarios, especially if your application requires complex URL patterns or parameter extraction. That’s why we use gorilla/mux
package for advanced routing.
gorilla/mux
is a powerful URL router and dispatcher for Go. It extends the capabilities of the standard net/http
package, providing additional features like route variables, subrouters, and middleware support. With gorilla/mux
, you can create complex routing structures for your web applications.
Before using gorilla/mux
, you need to install it. Open a terminal and run the following command to install:
go get -u github.com/gorilla/mux
Before installation, you have to run following command:
go mod init <module_name>
It creates a go. mod file that defines the module’s path and sets it up for dependency management.
Basic Routing
Let’s create a simple Go program that uses gorilla/mux
for basic routing:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Welcome to the homepage!")
})
http.ListenAndServe(":8080", router)
}
In this example, we create a new gorilla/mux router, define a route for the root path (”/”), and handle the request with a simple message.
Route Variables
gorilla/mux
allows you to capture variables from the URL.
Example:
router.HandleFunc("/user/{name}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
name := vars["name"]
fmt.Fprintf(w, "Hello, %s!", name)
}).Methods("GET")
In this example, the route /user/{name}
captures the name
variable from the URL and responds with a personalized greeting.
Route Patterns
gorilla/mux
supports flexible route patterns. For example, you can define routes with specific constraints or match patterns:
router.HandleFunc("/articles/{category:[a-z]+}/{id:[0-9]+}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
category := vars["category"]
id := vars["id"]
fmt.Fprintf(w, "Category: %s, ID: %s", category, id)
}).Methods("GET")
In this example, the route pattern:
/articles/{category:[a-z]+}/{id:[0-9]+}
ensures that category
is lowercase letters, and id
is numeric.
Subrouters
gorilla/mux
allows you to create subrouters, which can be useful for organizing routes:
apiRouter := router.PathPrefix("/api").Subrouter()
apiRouter.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "List of users")
}).Methods("GET")
apiRouter.HandleFunc("/users/{id}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
fmt.Fprintf(w, "User ID: %s", id)
}).Methods("GET")
In this example, all routes under the /api
path are grouped within a subrouter.
Middleware
gorilla/mux
supports middleware, allowing you to execute code before or after handling a request. Here’s a simple middleware example:
func LoggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Request received:", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
func main() {
router := mux.NewRouter()
// Apply the LoggingMiddleware to all routes
router.Use(LoggingMiddleware)
}
In this example, the LoggingMiddleware
logs information about each incoming request.
Handling HTTP Methods
gorilla/mux
makes it easy to handle different HTTP methods on the same route:
router.HandleFunc("/articles", func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
fmt.Fprint(w, "Get articles")
case http.MethodPost:
fmt.Fprint(w, "Create a new article")
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
})
In this example, the route /articles
responds differently based on the HTTP method used.