Comparison between Gin, Gorilla Mux and Net/Http

Comparison between Gin, Gorilla Mux and NetHttp's picture

As you may have guessed from the title, this blog is all about exploring the different web frameworks and packages, namely gin, gorilla mux and net/http. And we would also like to see how they differ from each other. We will inspect their attributes and consider which is best for creating HTTP servers. So, let us begin.

What is Gin? (Not Your Textbook Definition)

  • Gin is the most popular framework used by developers in Golang. Why? Well, it is an extremely fast web framework and it suits the requirements of developers when they create microservices and web applications.
  • With Gin, developers can wrap up the logic of a code within a very few statements. This is because most of the work has been done in the framework itself. It also makes the code easier to read.
  • By using reusable, modular components, it makes it straightforward to construct a request handling pipeline. In order to accomplish this, it enables you to create middleware that may be plugged into a single request handler, a number of them, or a collection of them.

Attributes of Gin that Makes it Popular

Now, that you know the basic about the Gin framework, it is time to take a look at the various features it has to offer:

  • Open-Source

The gin framework is open-source, which means you can get access to it for free. Furthermore, it is open to further and constant improvements from developers all around the world.

  • Lightning Fast

One of the quickest web frameworks out there is Golang Gin. It is based on the robust Gin gopher library, which makes it speedy and effective. It has radix tree based routing, which is a data structure, and helps in the chronological IP address organization.

  • Rendering Facilities
  1. A web application has the option of rendering a response in HTML, text, JSON, XML, or another format.
  2. Microservices and API endpoints often return data in response, frequently in JSON format.Gin offers a simple-to-use API for rendering XML, JSON and HTML.
  3. Gin can validate and parse a request's JSON, for instance, by making sure that all needed values are there.
  • Support for Middleware
  1. Middleware is a piece of code that can be run at any point during the handling of an HTTP request in the context of a Go web application.
  2. It is frequently used to group together common features that you wish to apply to several routes.
  3. Middleware can be used both before and after an HTTP request is processed. Middleware is frequently used for things like permission and validation.
  4. Gin enables us to create middleware that handles several routes while implementing some shared functionality. This keeps the codebase compact, and makes the code easier to maintain.
  • Routing
  1. One of the fundamental functions that all contemporary frameworks offer is routing. A URL may be used to reach any online page or API endpoint. Requests to these URLs are handled by frameworks using routes.
  2. Gin provides a quick router that is simple to set up and operate. Gin routers may support patterns and grouped URLs in addition to processing specific URLs. The groups can be infinitely nested without a decline in performance.

Creating a Sample REST API with the gin framework

Here, I am taking the code from https://github.com/GolangCompany/gin-api/blob/main/main.go

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) type News struct { Date int `json:"date" binding: "required"` Name string `json:"name" binding: "required"` } func main() { w := gin.Default() w.GET("", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "responseData": "Misha to sell exquisite gear", }) }) w.GET("/:newsupdate", func(c *gin.Context) { val := c.Param("newsupdate") c.JSON(http.StatusOK, gin.H{ "newsupdate": val, }) }) w.POST("/add", func(c *gin.Context) { var data News if err := c.ShouldBind(&data); err != nil { fmt.Println(err) c.JSON(http.StatusBadRequest, gin.H{ "error": fmt.Sprintf("%v", err), }) } else { c.JSON(http.StatusOK, gin.H{ "data": data, }) } }) w.Run("localhost:8080") }

What is Gorilla Mux? (In the Simplest Terms)

  • Gorilla Mux is one of the most powerful routers that helps in simplifying the route definitions.The multiplexer is capable of multiplexing HTTP routes to various handlers.
  • It is a package that customizes Go's built-in HTTP router. It has a ton of capabilities that help developers of web apps work more efficiently. The package can be used in conjunction with other HTTP libraries.
  • With gorilla mux, you get query-based matching, domain-based matching, path-based matching, sub-domain based matching and more.

Features of Gorilla Mux that Makes it Useful

Now, we will focus on the various features of Gorilla Mux and see why the package is so special. Moreover, we will learn how it is different from the Gin framework.

  • Support for the Middleware

When a match is found, Mux allows the inclusion of middlewares to a Router, which are then performed along with their subroutines in the order they were added.

  • Creation of Routers
  1. Similar to httprouter, the gorilla/mux package primarily aids in the creation of routers. The addition of a handler function to a specified URL distinguishes one of the two approaches.
  2. If we look closely, the Gorilla/Mux method of adding a handler resembles the fundamental ServeMux method. Gorilla/mux, in contrast to httprouter, condenses all the data of an HTTP request into a single request object.
  • Routing
  1. To visit every route that is registered on a router, you can utilize the Walk function on muxRouter.
  2. With Gorilla Mux, you can also restrict the routes to a domain or subdomain.
  3. The usage of routes as sub routers is possible; nested routes are only examined if the parent route matches. This is helpful for categorizing routes that have similar characteristics, such as a host, a path prefix, or other recurring qualities. Additionally, this improves request matching.
  • Requests
  1. According to the URL host, path, schemes, header, path prefix and query values, HTTP methods, or by utilizing custom matchers, requests can be matched.
  2. Requests for routes with an OPTIONS method matcher automatically cause CORSMethodMiddleware to set the Access-Control-Allow-Methods response header to all of the method matchers on the route.
  • Registered URLs
  1. Variables with an extra regular expression can be used with URL hosts, paths, and query values.
  2. It is possible to create registered URLs that are "reversed," which aids in keeping resource references.
  3. The route must be obtained before using the URL() function with a list of key/value pairs for the route variables.

Creating a Sample REST API with Gorilla Mux

In this section, we are going to see the creation of a sample REST API using the gorilla mux library.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 package main import ( "encoding/json" "log" "math/rand" "net/http" "strconv" "github.com/gorilla/mux" ) type Movie struct { Film string `json:"film"` Lead *Lead `json:"lead"` } type Lead struct { Firstname string `json:"firstname"` Lastname string `json:"lastname"` } var movies []Movie func startMovies(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(movies) } func createMovie(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var movie Movie _ = json.NewDecoder(r.Body).Decode(&movie) movie.ID = strconv.Itoa(rand.Intn(100000000)) // Mock ID - not safe movies = append(movies, movie) json.NewEncoder(w).Encode(movie) } func main() { r := mux.NewRouter() movies = append(movies, Movie{Film: "Cobra", Lead: &Lead{Firstname: "Sylvester", Lastname: "Stallone"}}) movies = append(movies, Movie{Fim: "Schindler's List", Lead: &Lead{Firstname: "Liam", Lastname: "Neeson"}}) r.HandleFunc("/movies", startMovies).Methods("GET") r.HandleFunc("/movies", createMovie).Methods("POST") log.Fatal(http.ListenAndServe(":8000", r)) }

Considering a Few Points to Differentiate between Gin and Gorilla Mux

  1. Developers are of the opinion that with gorilla mux, they find the routing to be easier and flexible. With the gin framework, they often run into unforeseen scenarios which they cannot resolve.
  2. Most of the developers opt for gorilla mux to get the job done of adding middlewares and stating route definitions. If they want extra features, they choose gin for customized response writing, validation, outputting JSON, etc.
  3. Many developers believe that it is wise to stick to lightweight packages like gorilla mux instead of heavy frameworks like gin. They are all for using the standard libraries in Golang.
  4. With gin, you have your work cut out for you as you have to learn quite a bit. Gorilla mux, on the other hand, sticks with the handler signature of Golang, so you do not have to spend time learning it.
  5. Most developers are reluctant to use the gin framework even though it makes the program less convoluted. Since the framework adds additional dependencies to the project, it sometimes leads to compatibility issues. The framework is not fully idiomatic and all the recent upgrades in Golang have not been incorporated into it.

If you take a look at the graph below, you will find that developers tend to lean more towards the gorilla mux library in comparison to the gin framework.

gorilla mux library in comparison to the gin framework

What is the net/http Package in Golang?

Introduction

It is one of the most important and simplest packages that any developer has to be familiar with. Well, what is the package used for? This package allows you to create powerful HTTP servers in Golang with potent compositional constructs.

Purpose

Developers are able to create HTTP requests with the help of http.Post, http. Get to help one perform CRUD operations. The package is also useful for routing and response objects.

Advantage

The package allows for the code to be kept simple and precise. If you use frameworks like Beego or gin, the same fundamentals apply. However, the processes are a bit different.

General Steps

In order to use the package properly, one has to begin with using the http.Handlefunc function which lets the server know which function it has to call to take care of HTTP requests. Following this, the general practice is to use the http.ListenAndServe that helps in initiating the server and makes the latter pay heed to the requests.

Creating a Sample REST API with net/http

In this section, you will get to notice the code that I will use to create a sample REST API.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package main import ( “fmt” “log” “net/http” “encoding/json” ) type Book struct { Title string `json:”title”` Pages int `json:”pages”` Author string `json:”author”` } var Books []Book func Commence(w http.ResponseWriter, r *http.Request){ fmt.Fprintf(w, “Let’s Begin”) fmt.Println(“Endpoint Hit: Book Details”) } func returnAllBooks(w http.ResponseWriter, r *http.Request){ fmt.Println(“Endpoint Hit: returnAllBooks”) json.NewEncoder(w).Encode(Books) } func handleRequests() { http.HandleFunc(“/”, Commence) http.HandleFunc(“/books”, returnAllBooks) log.Fatal(http.ListenAndServe(“:8080”, nil)) } func main() { Books = []Book{ Book{Title: “The Long Walk”, Pages: 384, Author: “Richard Buckman”}, Book{Title: “To Kill A MockingBird”, Pages: 281, Author: “Harper Lee”}, handleRequests() }

How Does net/http Differs from Gorilla Mux?

  • The net/http package is sufficient for most developers when it comes to creating web servers. Having said that, the gorilla mux eases the development process especially if you wish to create a complex REST API.
  • For fixed URL pathways, net/http's ServeMux http's does an excellent job of routing inbound requests; but, for nice paths that employ variables, you will need to create a custom multiplexer while using Gorilla, for which you are receiving no charge.
  • With the normal http.ServeMux, it is difficult to provide RESTful resources with appropriate HTTP methods.
  • Requests can be matched using the URL host, schemes, header and query values, path prefix,and HTTP methods with gorilla's mux package.

When it comes to the usage preference, you will get to see that most developers rely on the gorilla mux library in comparison to the net/http package. This is simply because the gorilla mux offers a number of facilities.

gorilla mux library in comparison to the net/http package

How Does net/http Differs from Gin framework?

  • Gin includes route registration wrappers, so there is minimal boilerplate. Gin provides a couple more handy deserialization wrappers, so you won't have to bother about the boilerplate surrounding the JSON.unmarshal operation.
  • Gin takes advantage of httprouter, which is faster than the operations to be executed by net/http package. The gin.Context object nicely abstracts away from the request/response, so we don't need a switch statement to determine the request's method.
  • When it comes to path parameters, gin makes the process easier with tokens. On the contrary, if you are to make complex paths, then net/http is not a suitable option.
  • When it comes to middleware, both the net/http package and gin framework have their own advantages. The only difference is that with the gin framework there is less coding.

As far as the usage of both the net/http package and the gin framework is concerned, you can see the preference among developers from the graph showcased below.

net/http Differs from Gin framework

Hopefully, you have understood the differences between gin framework, gorilla mux and the net/http package. In order to comprehend the functional differences, it is only ideal that you concoct programs and see the execution differences.

Build Your Golang Team