One of the key features of any web application is its routing mechanism. Routing refers to the process of directing incoming requests to the appropriate handler functions. Golang provides a built-in net/http package for routing, but it can be limited in terms of flexibility and scalability. This is where Golang Gorilla Mux comes in. In this article, we will explore the basics of Gorilla Mux in Golang and its advantages over the standard net/http
package.
What is Gorilla Mux in Go?
Golang Gorilla Mux is a powerful URL router and dispatcher for Golang web applications. It is built on top of the net/http package and provides additional features and flexibility.
Key benefits of using Golang Gorilla Mux:
- Powerful URL routing: Gorilla Mux provides a flexible and powerful URL router that allows you to define complex URL patterns and handle HTTP requests with ease.
- Middleware support: Gorilla Mux supports middleware, which enables you to add custom functionality to your web application without having to modify your core code.
- High performance: Gorilla Mux is built with performance in mind and is optimized for high throughput and low latency.
- Support for subrouters: Gorilla Mux allows you to create subrouters, which makes it easy to organize and modularize your code.
Using Gorilla Mux in your Go Project
How to Install Gorilla Mux
Before we can start using Gorilla Mux, we need to install it. The easiest way to install Gorilla Mux is to use the go get command:
go get -u github.com/gorilla/mux
This will download and install the Gorilla Mux package in your GOPATH.
Import Gorilla Mux in Go
Once you have installed Go Gorilla Mux, you can import it into your project:
import "github.com/gorilla/mux"
Understanding Router & Route Struct
In Gorilla Mux, routes are defined using the Route
struct, while the router is defined using the Router
struct. Now, we will explore the differences between the two structs and how they are used in Gorilla Mux.
Router Struct
The Router
struct in Gorilla Mux is used to define a collection of routes and to match incoming requests to the appropriate route.
type Router struct {
// contains filtered or unexported fields
}
Router
struct has various methods for defining routes, including Handle()
, HandleFunc()
, Path()
, Methods()
, and more. These methods allow you to define the URL pattern, HTTP method, and handler function for each route.
Example:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, world!")
})
http.ListenAndServe(":8080", r)
}
In this example, we create a new Router
using mux.NewRouter()
. We then define a route for the URL pattern “/hello” using HandleFunc()
. The route handler function simply writes “Hello, world!” to the HTTP response.
Route Struct
The Route
struct in Gorilla Mux is used to define a single route.
type Route struct {
// contains filtered or unexported fields
}
Route
struct has various methods for defining the URL pattern, HTTP methods, and handler function for the route. These methods include Path()
, Methods()
, Handler()
, and more.
Example:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
// Define a route with multiple HTTP methods
route := r.Path("/hello").Methods("GET", "POST").Subrouter()
route.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, world!")
})
http.ListenAndServe(":8080", r)
}
In this example, we define a route for the URL pattern “/hello” using the Path()
method. We then use the Methods()
method to specify that the route should only match HTTP GET and POST requests. Finally, we define the route handler function using HandleFunc()
.
Golang Gorilla Mux NewRouter
In Golang Gorilla Mux, mux.NewRouter()
is a function that creates a new router instance. The router is responsible for matching incoming requests against a list of registered routes and calling the associated handler function for each matched route.
Gorilla Mux NewRouter Syntax
func NewRouter() *Router
Create a new router instance using mux.NewRouter()
:
router := mux.NewRouter()
When you call mux.NewRouter()
, it creates a new instance of the Router
struct, which represents a router that can be used to handle incoming HTTP requests.
This struct contains all the necessary methods and data structures for defining routes, matching URL patterns, and handling requests.
Custom Handle Using Gorilla Mux in Go
Handle()
is a powerful method provided by the Golang Gorilla Mux library that allows developers to define routes for their web applications with great flexibility and control.
Handle Syntax
func (r *Router) Handle(path string, handler http.Handler) *Route
The Handle()
method takes two arguments: the URL pattern to match, and a Handler.
To define routes using Handle(), we first need to create a new router using the NewRouter() function.
Once we have created the router, we can use the Handle()
method to define routes. Here is an example of how to define a route that matches the pattern /books/{title}
:
router := mux.NewRouter()
router.Handle("/books/{title}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
title := vars["title"]
fmt.Fprintf(w, "You requested the book: %s", title)
})).Methods("GET")
In this example, we define a new route using Handle() that matches the pattern /books/{title}
. We also specify that this route only responds to HTTP GET requests using the Methods() method.
When this route is matched, the function provided as the second argument to Handle() is executed. This function extracts the book title from the URL using the Vars() function, and then writes a response back to the client.
Handle() can also be used to define routes that respond to multiple HTTP methods. Here is an example of how to define a route that responds to both HTTP GET and POST requests:
router.Handle("/books", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
fmt.Fprintln(w, "You requested the book list")
case "POST":
fmt.Fprintln(w, "You submitted a new book")
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}))
In this example, we define a new route using Handle() that matches the pattern /books
. We then use a switch statement to handle both HTTP GET and POST requests. If a request with any other HTTP method is received, we return an HTTP 405 error using the http.Error() function.
Routing with HandleFunc in Gorilla Mux
The HandleFunc()
method takes two arguments: a URL path pattern and a function that is executed when the pattern is matched.
HandleFunc Syntax
func (r *Router) HandleFunc(path string, f func(http.ResponseWriter, *http.Request)) *Route
The function should take two arguments: an http.ResponseWriter
and an http.Request
. The http.ResponseWriter
is used to write the response to the client, while the http.Request
contains information about the incoming request, such as the HTTP method, headers, and URL parameters.
package main
import (
"net/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
http.ListenAndServe(":8000", r)
}
In this example, we create a new Gorilla Mux router using the NewRouter() function. We then define a route for the root URL (“/”) using the HandleFunc() method.
The HandleFunc() method takes two arguments: the first argument is the URL path to match, and the second argument is the handler function to execute when the URL is matched.
In this case, the handler function simply writes the string “Hello, World!” to the response writer.
We then start the HTTP server using the ListenAndServe() function, passing in our router as the second argument.
Path-Based Matching in Gorilla Mux
As we mentioned earlier, Gorilla Mux supports path-based matching, which allows for more fine-grained routing of requests. Let’s take a look at an example:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/articles", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("List of articles"))
})
router.HandleFunc("/articles/{id}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
fmt.Fprintf(w, "Article ID: %v", id)
})
http.ListenAndServe(":8000", r)
}
In this example, we define two routes: one for the “/articles” URL and another for the “/articles/{id}” URL. The “{id}” part of the URL is a placeholder for a variable, which can be extracted using the Vars() method of the request context. In the handler function for the “/articles/{id}” URL, we extract the “id” variable and write it to the response writer.
Handle URL Parameters Using Gorilla Mux Vars
Gorilla Mux also makes it easy to handle URL parameters. Here’s an example of how to define a route that accepts a parameter:
router.HandleFunc("/users/{id}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
w.Write([]byte("User ID: " + id))
}).Methods("GET")
In this example, we define a route for the /users/{id}
URL pattern. The {id}
portion of the pattern is a variable that can match any value. Inside the handler function, we use the Vars
function to retrieve the value of the id
variable and then write it to the response.
Handle Query Parameters
Query parameters are a way to pass additional information to a web server through the URL. They are specified after the “?” character in the URL and are formatted as key-value pairs separated by the “&” character. For example:
https://hackthedeveloper.com/search?q=golang&sort=recent
In the above example, “q” and “sort” are query parameters with values “golang” and “recent” respectively.
In Gorilla Mux, we can handle query parameters using the r.URL.Query()
function. This function returns a map of query parameter names to their corresponding values.
Let’s update our getUser()
function to handle a query parameter “details”:
func getUser(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
userID := params["id"]
// Fetch user details from the database using the userID
// Handle query parameter "details"
details := r.URL.Query().Get("details")
if details != "" {
fmt.Fprintf(w, "User details with extra info for user %s", userID)
} else {
fmt.Fprintf(w, "User details for user %s", userID)
}
}
In the above code, we are using the Get()
function of the query parameter map to extract the value of the “details” parameter. We then use this value to determine whether to return just the user details or user details with extra information.
Note that we are using the Get()
function instead of directly accessing the map using r.URL.Query()["details"]
. This is because the Get()
function returns an empty string if the parameter does not exist, whereas accessing the map directly would result in a panic if the parameter does not exist.
We can test our updated function by sending a GET request to “/users/1?details=true”:
$ curl http://localhost:8080/users/1?details=true
User details with extra info for user 1
If we omit the “details” parameter, we will get only the user details:
$ curl http://localhost:8080/users/1
User details for user 1
In this way, we can handle query parameters in Gorilla Mux and use them to add additional functionality to our web applications.
Handling Query Parameters Using Gorilla Mux in Go
In addition to handling routes and URL patterns, Golang Gorilla Mux also provides a powerful mechanism for handling queries with the Queries()
method of the mux.Router
object.
The Queries()
method allows you to define a set of query parameters that must be present in the URL for the route to match. Here’s an example of how to use the Queries()
method:
router := mux.NewRouter()
router.HandleFunc("/articles", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
category := vars["category"]
author := vars["author"]
fmt.Fprintf(w, "Category: %s, Author: %s", category, author)
}).Queries("category", "{category}", "author", "{author}")
In this example, we define a route for URLs that match the pattern /articles
, but only if they also contain the category
and author
query parameters. When this route is matched, we extract the values of the category
and author
query parameters using the mux.Vars()
function and write them to the response writer.
Matching Query using Regular Expression in Gorilla Mux
You can also use regular expressions to match query parameters with the QueriesRegexp()
method.
Here’s an example of how to use the QueriesRegexp()
method:
r := mux.NewRouter()
r.HandleFunc("/articles", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
category := vars["category"]
author := vars["author"]
fmt.Fprintf(w, "Category: %s, Author: %s", category, author)
}).QueriesRegexp("category", "[a-zA-Z]+", "author", "[a-zA-Z]+")
In this example, we define a route for URLs that match the pattern /articles
, but only if they also contain the category
and author
query parameters, which must be alphanumeric strings. When this route is matched, we extract the values of the category
and author
query parameters using the mux.Vars()
function and write them to the response writer.
By using the Queries()
and QueriesRegexp()
methods, you can easily handle requests with specific query parameters in your Gorilla Mux-based web application.
These methods provide a powerful and flexible way to define URL patterns that match specific query parameters, making it easy to build complex web applications with precise URL handling requirements.
HTTP Methods in Gorilla Mux
The Methods()
function in Gorilla Mux is a method of the NewRouter()
function that allows you to specify which HTTP methods a route should match.
Methods Syntax
func (r *Router) Methods(methods ...string) *Route
This function takes one or more HTTP methods as arguments and returns a *Route
object, which can be further customized by calling additional methods.
Here’s an example of how to use the Methods()
function:
router := mux.NewRouter()
router.HandleFunc("/users", getUsers).Methods("GET")
router.HandleFunc("/users", createUser).Methods("POST")
In this example, we create a new router using mux.NewRouter()
. We then define two routes for the /users
URL. The first route matches the GET
HTTP method and calls the getUsers
function, while the second route matches the POST
HTTP method and calls the createUser
function.
Multiple HTTP Methods using Gorilla Mux in Go
You can also use the Methods()
function to match multiple HTTP methods:
router := mux.NewRouter()
router.HandleFunc("/users", getUsers).Methods("GET", "HEAD")
router.HandleFunc("/users", createUser).Methods("POST")
In this example, we create two routes for the /users
URL. The first route matches the GET
and HEAD
HTTP methods, while the second route matches the POST
HTTP method.
Headers in Golang Gorilla Mux
HTTP headers are an important aspect of web applications. They provide additional information about the request or the response, such as the content type or the encoding. In Gorilla Mux, the Headers()
method allows you to set or modify HTTP headers for your application.
The Headers()
method is part of the NewRouter()
function in Gorilla Mux. It allows you to set default headers for all routes in your application.
router := mux.NewRouter()
router.Headers("Content-Type", "application/json")
In this example, we create a new router using the mux.NewRouter()
function. We then set the Content-Type
header to application/json
for all routes in the application using the Headers()
method.
Set Multiple Headers Using Gorilla Mux
You can also use the Headers()
method to set multiple headers at once.
router := mux.NewRouter()
router.Headers("Content-Type", "application/json", "X-Frame-Options", "SAMEORIGIN")
In this example, we set both the Content-Type
and X-Frame-Options
headers for all routes in the application.
Set Headers In Specific Route using Gorilla Mux
You can also modify or remove headers for specific routes in your application. To do this, you can use the Headers()
method on a specific route.
router := mux.NewRouter()
router.HandleFunc("/example", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintln(w, "Hello, world!")
}).Headers("Content-Type", "application/json")
In this example, we define a route for the /example
URL using the HandleFunc()
method. We then set the Content-Type
header to text/plain
for this specific route using the Header().Set()
method on the response writer.
Finally, we set the Content-Type
header to application/json
for all other routes in the application using the Headers()
method.
Gorilla Mux StrictSlash Method
In Golang Gorilla Mux provides a strict slash setting that allows you to define whether your router should be strict or relaxed when it comes to trailing slashes in URLs.
The strict slash setting is disabled by default, which means that Gorilla Mux will treat URLs with or without trailing slashes as equivalent. However, in some cases, you may want to enable strict slash mode to ensure that your URLs are consistent and to avoid potential issues with duplicate content.
Strict slash mode in Gorilla Mux enforces the presence or absence of a trailing slash in URLs. When strict slash mode is enabled, URLs with a trailing slash are treated as a different URL than URLs without a trailing slash. This means that if you define a route for /hello/
, it will not match a request for /hello
in strict slash mode, and vice versa.
StrictSlash Syntax
func (r *Router) StrictSlash(value bool) *Router
Enabling strict slash mode in Gorilla Mux is simple. You can enable strict slash mode for a single route or for your entire router.
Strict Slash for a Single Route
To enable StrictSlash
for a single route, you can use the StrictSlash(true)
method when defining the route:
func main() {
router := mux.NewRouter()
// Route with StrictSlash enabled
strictSlashRoute := router.Path("/hello/").Methods("GET")
strictSlashRoute.HandlerFunc(helloHandler)
strictSlashRoute.StrictSlash(true)
// Other routes
router.Path("/other").Methods("GET").HandlerFunc(otherHandler)
http.ListenAndServe(":8080", r)
}
In this example, we’ve defined a route for /hello/
that has StrictSlash
enabled by calling the StrictSlash(true)
method. This means that if a request is made to /hello
without a trailing slash, Gorilla Mux will automatically redirect the request to /hello/
.
http://localhost:8080/hello/ -> 404 page not found
http://localhost:8080/hello -> Hello, world!
When you enable the StrictSlash
method for a specific route in Gorilla Mux, it means that this route will be more strict about trailing slashes in URLs than the other routes.
However, you need to keep in mind that enabling StrictSlash
for a single route will override the global setting of the router.
For example, if you have enabled StrictSlash
globally for all routes in your Gorilla Mux router, but then you disable it for a specific route using StrictSlash(false)
, this particular route will no longer be strict about trailing slashes.
In other words, the global setting will be ignored for the particular route.
Strict Slash for entire router
You can also enable strict slash mode for your entire router by passing the StrictSlash(true)
option when creating your router:
router := mux.NewRouter().StrictSlash(true)
In this example, we create a new router and enable strict slash mode for the entire router using the StrictSlash()
method.
Strict slash mode is useful in situations where you want to ensure that your URLs are consistent and avoid potential issues with duplicate content. For example, if you have a web page with a URL that ends with a trailing slash, you may want to ensure that all requests to that page include the trailing slash to avoid creating duplicate content.
Similarly, if you have a RESTful API that expects URLs to end with a trailing slash, enabling strict slash mode can help ensure that your API endpoints are consistent and avoid potential issues with malformed URLs.
Skipping URL Cleaning in Gorilla Mux
SkipClean() is a function available in Gorilla Mux’s NewRouter method that can be used to disable URL path cleaning for a specific route.
SkipClean Syntax
func (r *Router) SkipClean(value bool) *Router
By default, Gorilla Mux cleans the URL path and removes any trailing slashes or empty path segments. However, in some cases, you may want to disable this behavior for certain routes.
Gorilla Mux Skip Clean Example
Here’s an example of how to use SkipClean() in Gorilla Mux:
r := mux.NewRouter()
r.HandleFunc("/articles/", ArticlesHandler).Methods("GET").SkipClean(true)
In this example, we create a new router using the mux.NewRouter()
method. We define a route for the /articles/
URL path and set the HTTP method to “GET” using the Methods()
method. We also call the SkipClean()
method with the value of true
to disable URL path cleaning for this specific route.
Let’s take a look at how this affects the URL path cleaning behavior of Gorilla Mux. Without SkipClean(), Gorilla Mux will automatically clean the URL path and remove any trailing slashes or empty path segments. For example, if a user navigates to the URL path /articles///
, Gorilla Mux will automatically clean the URL path and redirect the user to the URL path /articles
. However, if we enable SkipClean() for the /articles/
route, Gorilla Mux will no longer clean the URL path and will allow the user to access the URL path with trailing slashes and empty path segments.
Here’s an example of how this behavior looks in action:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func ArticlesHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
fmt.Fprintf(w, "Category: %v\n", vars["category"])
fmt.Fprintf(w, "ID: %v\n", vars["id"])
}
func main() {
r := mux.NewRouter()
// Enable SkipClean for the /articles/ route
r.HandleFunc("/articles/", ArticlesHandler).Methods("GET").SkipClean(true)
http.ListenAndServe(":8080", r)
}
If we navigate to the URL path /articles///tech/123
, Gorilla Mux will return the following output:
Category: tech
ID: 123
As you can see, Gorilla Mux has allowed the trailing slashes and empty path segments in the URL path and has passed the full path to the ArticlesHandler()
function.
By using SkipClean()
, you can ensure that certain routes in your web application are not modified by the URL cleaning process. This can be useful in cases where you need to preserve the exact URL path or query string parameters for a particular route.
It’s important to note that SkipClean()
should be used with caution, as it can potentially cause issues with routing and matching if used incorrectly.
It should only be used when you are sure that skipping the cleaning process is necessary for a particular route.
Using Middleware with Gorilla Mux
Use()
is a powerful method in Golang Gorilla Mux that allows you to add middleware functions to your router.
Middleware functions are functions that execute before or after a request is handled by the router. They are often used to modify the request or response objects, add authentication or logging, or perform other tasks that are required for a web application to function properly.
Use Syntax
func (r *Router) Use(mwf ...MiddlewareFunc)
The Use()
method can be called on a mux.Router
object to add one or more middleware functions to the router. The syntax for using the Use()
method is as follows:
router := mux.NewRouter()
router.Use(middleware1, middleware2, middleware3)
In this example, we create a new router using the mux.NewRouter()
function, and add three middleware functions to the router using the Use()
method. These middleware functions will be executed in the order they are added, before any request is handled by the router.
A middleware function is a function that takes two arguments: an http.ResponseWriter
and an http.Request
object. The http.ResponseWriter
object is used to write the response to the client, while the http.Request
object contains information about the incoming request.
Gorilla Mux Middleware Example
Here’s an example of a simple middleware function that logs the incoming request:
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("Incoming request: %s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
In this example, we define a middleware function called loggingMiddleware
that logs the HTTP method and URL path of the incoming request using the log.Printf()
function. We then call the next.ServeHTTP()
method to pass the request and response objects to the next middleware function in the chain.
To add this middleware function to our router, we can call the Use()
method on the router and pass the middleware function as an argument:
r := mux.NewRouter()
r.Use(loggingMiddleware)
In this example, we create a new router using the mux.NewRouter()
function, and add the loggingMiddleware
function to the router using the Use()
method. This middleware function will be executed for every request that is handled by the router, and will log the incoming request before passing it to the next middleware function.
Using middleware functions with Gorilla Mux can greatly simplify the process of adding common functionality to your web application, such as authentication, logging, or request/response modification.
By adding middleware functions to your router using the Use()
method, you can easily extend the functionality of your application without duplicating code or creating complex logic.
Group Routes with PathPrefix() in Gorilla Mux
The PathPrefix()
function is used to create a new router that matches the URL prefix. This function takes a single argument, which is the URL prefix to match.
PathPrefix Syntax
func (r *Router) PathPrefix(tpl string) *Route
Here’s an example of how to use PathPrefix()
to define a route that matches a URL prefix:
router := mux.NewRouter()
api := router.PathPrefix("/api").Subrouter()
api.HandleFunc("/users", getUsersHandler)
In this example, we create a new router using mux.NewRouter()
. We then define a sub-router api
using the PathPrefix()
function, which matches the prefix “/api”. Finally, we define a route for the “/users” URL under the “api” sub-router using the HandleFunc()
method.
When a request is made to “/api/users”, the getUsersHandler
function will be executed. The PathPrefix()
function ensures that only requests with a URL that starts with “/api” will be routed to this sub-router.
One of the advantages of using PathPrefix()
is that it allows you to group related routes together under a common URL prefix. This can help to keep your code organized and make it easier to maintain.
Using Variables in PathPrefix Gorilla Mux
In some cases, you might need to define a route prefix that contains a variable value. For example, if you are building an API that has versioning, you might want to prefix your routes with the version number. In such cases, you can use a variable in the PathPrefix() method of the Gorilla Mux NewRouter().
Example of how to use a variable in the PathPrefix() method:
r := mux.NewRouter()
version := "v1"
r.PathPrefix("/" + version).HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "This is version", version)
})
We define a route prefix using the PathPrefix() method and concatenate the version variable to the string “/”. Finally, we define a handler function that writes the version number to the response writer.
Note that you can use any variable value in the PathPrefix() method. For example, if you are using a configuration file to define your route prefixes, you can read the value from the file and use it in the PathPrefix() method.
In addition to using variables in the PathPrefix() method, you can also use regular expressions to define more complex route prefixes. For example, if you want to match URLs that contain a specific word, you can use a regular expression in the PathPrefix() method.
r := mux.NewRouter()
r.PathPrefix("/{category:(news|sports|politics)}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
category := vars["category"]
fmt.Fprintf(w, "This is the %s category page", category)
})
In the above example, we define a route prefix using a regular expression that matches URLs that contain the words “news”, “sports”, or “politics”. When this route is matched, we extract the category value from the URL using the Vars() method and write it to the response writer.
Subrouter in Golang Gorilla Mux
In Golang Gorilla Mux, the Subrouter()
method allows you to create a new router that inherits all the routes and middleware from its parent router. This can be useful when you want to group related routes together under a common URL prefix.
Subrouter Syntax
func (r *Route) Subrouter() *Router
To create a subrouter, you first need to create a parent router using the mux.NewRouter()
function. Once you have a parent router, you can create a subrouter using the Subrouter()
method:
Gorilla Mux Subrouter Example
parentRouter := mux.NewRouter()
subRouter := parentRouter.PathPrefix("/api").Subrouter()
In this example, we create a parent router using mux.NewRouter()
. We then create a subrouter using the Subrouter()
method and set the path prefix to /api
using the PathPrefix()
method. Any routes added to the subrouter will have the prefix /api
added to their URLs.
You can add routes to the subrouter in the same way as you would with the parent router. Here’s an example:
subRouter.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
// Handle users request
}).Methods("GET")
In this example, we define a route for the /users
URL pattern using the HandleFunc()
method. We also set the HTTP method to GET
using the Methods()
method. This route will be matched by requests to /api/users
.
Subrouters also inherit middleware from their parent router. This means that any middleware added to the parent router will be executed for all routes in the subrouter. Here’s an example:
parentRouter.Use(loggingMiddleware)
subRouter.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
// Handle users request
}).Methods("GET")
In this example, we add a logging middleware to the parent router using the Use()
method. This middleware will be executed for all routes in the subrouter, including the /users
route.
Subrouters can also be nested, allowing you to create multiple levels of routing hierarchy. Here’s an example:
parentRouter := mux.NewRouter()
v1Router := parentRouter.PathPrefix("/v1").Subrouter()
usersRouter := v1Router.PathPrefix("/users").Subrouter()
usersRouter.HandleFunc("", func(w http.ResponseWriter, r *http.Request) {
// Handle users request
}).Methods("GET")
In this example, we create a parent router using mux.NewRouter()
. We then create a subrouter for version 1 of our API using the PathPrefix()
method. Finally, we create a subrouter for the /users
URL pattern under the version 1 router.
By using subrouters, you can create a clean and organized structure for your web application’s routes and middleware, making it easier to manage and maintain your code.
Handle Undefined URLs in Gorilla Mux with NotFoundHandler()
In Golang Gorilla Mux provides a NotFoundHandler() function that can be used to handle requests for URLs that do not match any of the defined routes. The NotFoundHandler() function is part of the NewRouter() function that returns a new router instance.
Gorilla Mux NotFoundHandler Example
Here’s an example of how to use the NotFoundHandler() function:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
// Define some routes
r.HandleFunc("/", homeHandler)
r.HandleFunc("/about", aboutHandler)
// Use the NotFoundHandler() function to handle requests for undefined URLs
r.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "404 Not Found")
})
// Start the server
http.ListenAndServe(":8080", r)
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome to the home page!")
}
func aboutHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Learn more about us on the about page!")
}
In this example, we define a new router instance and define two routes for the “/” and “/about” URLs. We then use the NotFoundHandler() function to define a custom handler function that is called when a request is made for an undefined URL. In this case, we simply return a 404 Not Found status code and a custom message.
When we run this program and try to access a URL that is not defined, such as “/contact”, we will see the custom 404 message:
$ curl http://localhost:8080/contact
404 Not Found
By using the NotFoundHandler() function in Gorilla Mux, you can handle requests for undefined URLs in a custom way and provide a better user experience for your web application’s users.
Gorilla Mux NotFoundHandler Custom 404 Page Example
The NotFoundHandler() function can also be used to redirect users to a custom 404 page or to another page within the application.
func main() {
r := mux.NewRouter()
// Define some routes
r.HandleFunc("/", homeHandler)
r.HandleFunc("/about", aboutHandler)
// Use the NotFoundHandler() function to redirect to a custom 404 page
r.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/404", http.StatusSeeOther)
})
// Define the custom 404 page handler
r.HandleFunc("/404", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Oops! The page you're looking for cannot be found.")
})
// Start the server
http.ListenAndServe(":8080", r)
}
In this example, we define a custom 404 page handler function and use the NotFoundHandler() function to redirect users to this page when they request an undefined URL. We use the http.Redirect() function to redirect the user to the custom 404 page with a 303 See Other status code.
By using the NotFoundHandler()
function in combination with custom handler functions and redirects, you can create a more robust and user-friendly web application with Gorilla Mux.
Wrapping Up
In conclusion, Gorilla Mux is a powerful and flexible router for building web applications in Golang. It provides a wide range of features for defining routes and handling HTTP requests, including regular expressions, middleware, subrouters, and more.
In this blog, we’ve covered the basics of Gorilla Mux, including how to create a new router, define routes, and handle requests. We’ve also explored some of the more advanced features of Gorilla Mux, such as regular expressions and middleware, and provided code examples to help you get started.
By using Gorilla Mux in your Golang web applications, you can create clean and maintainable code that is easy to read and understand. With its intuitive API and rich feature set, Gorilla Mux is a must-have tool for any Golang developer building web applications.
We hope that this blog has provided you with a comprehensive understanding of Gorilla Mux and how to use it to build powerful web applications. If you have any questions or feedback, feel free to leave a comment or reach out to us directly.
References
- Gorilla Mux documentation: https://pkg.go.dev/github.com/gorilla/mux
- Golang net/http package documentation: https://golang.org/pkg/net/http/
- Golang official website: https://golang.org/