Golang Gorilla Mux: The Ultimate Router for Web Apps

Rate this post

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:

  1. 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.
  2. Middleware support: Gorilla Mux supports middleware, which enables you to add custom functionality to your web application without having to modify your core code.
  3. High performance: Gorilla Mux is built with performance in mind and is optimized for high throughput and low latency.
  4. 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

Leave a Reply

Your email address will not be published. Required fields are marked *