Go with Gin 🍺

Maneesha Indrachapa
7 min readAug 28, 2022

When you read the title of this article you may be wondering if this article is about some alcohol thing but it is not. The Gin framework is the most popular HTTP framework using the Go language.

What is Gin?

First, let’s see what is this Gin. According to the Gin documentation

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API but with performance up to 40 times faster than Martini. If you need a smashing performance, get yourself some Gin.

So basically Gin is a framework which helps to create Web API in a globally recognized standard way which has really good performance compared to the other programming language frameworks.

Create API endpoints using the Gin framework

Let's see how we can use this Gin framework and build some basic endpoints so you can have an idea of how to use the framework to create simple endpoints. We will use the same source code which we used in the previous article (Go with .env files using Viper)

First, we need to add the Gin framework to our project as a library, to do that you need to open the command prompt and run the below command

go get -u github.com/gin-gonic/gin

What we are going to create is endpoints to get some champion details, add champions, delete champions and update champion details.

create a folder named routes in your root folder and create a go file named routes.go. Let’s add some basic details that will need to create APIs

  • var Router = gin.Default() — First what we need is a variable which can hold gin.Default() value.gin.Default() creates a Gin router with default middleware(logger and crash-free recovery middleware).
  • var champions = map[string]string — we create another variable which is a map which we can store the champion name and that champion's favourite quote
  • func InitRoutes() — Inside this function, we initialize the API endpoints in the Gin framework we can group the routes which have the same prefixes. So we will create another variable and group the paths publicRoutes := Router.Group(“v1/”)

GET request (Sample Health- Check endpoint)

First import the net/http package to the project and create a health endpoint

So we create a function func HealthCheck(context *gin.Context) in the function, we pass context which is a type of gin.Context

The gin Context is a structure that contains both the http.Request and the http.Response that a normal http.Handler would use, plus some useful methods and shortcuts to manipulate those.

then we return,

context.JSON(http.StatusOK, gin.H{ “message”: “API is up and working fine” })

In the Gin framework H is a shortcut for map[string]interface{}
So H means something like this type H map[string]interface{}

That is to say,

Json (http.statusok, gin.h {“message”: “API is up and working fine”})

Equivalent to

Json (http.statusok, map [string] interface {} {“message”: “API is up and working fine”})

Then we add the endpoint to the router, inside the InitRoutes() the function we add publicRoutes.GET(“health”, HealthCheck) so whenever we are going to add a route in Gin we need to define

You can get an idea from the above image why we need each thing. Now go to your main.go file and run the InitRoutes() method and start the server.

We can see that our health check endpoint is working.

GET request with Query Parameters

Now let's create a function to get a champion quote when we provide the champion name as a query parameter

So we create a new function GetChampion() and map that function to the route champion inside the InitRoute() function. Let's try to understand what I did in the function GetChampion()

First I create a variable championwith the short declaration operator and map that to the context.Query(“championName”) so whenever I pass a champion name in query params it will assign it to the champion variable.

Next, let's try to understand what happened in the below code block

When getting a value from the map in go language we can assign two values

  • championQuote will receive either the value of championfrom the map or a "zero value" (in this case the empty string)
  • ok will receive a bool that will be set to true if champion was actually present in the map

if champion was not on the map ok the value will be false so we handle it inside the if clause. if ok value is false we will return that “champion does not exist” with an error code http.StatusNotfound which is 404. Else we will return context.JSON(http.StatusOK, gin.H{ champion: championQuote, })

Okay now, let's try our endpoint with the postman.

Returned with 200 success code
Returned with 404 status not found code

POST request with JSON

Now let's create a POST request which can use to add a new champion and champion quote to our map.

First, we create a champion struct which we can use to map the JSON values

in the struct, you can see we are using Name (first letter is capital it means it can access the public) which is a string and we map it to the JSON value of name . Like the name, we map Quote to the JSON value of quote

Next, we create a variable which is var championReq Champion it means that the variable championReq is only initialized as a Champion struct type variable. We are going to use this variable to map the JSON request we get from the request.

Now let's see theAddChampion()function,

As same we pass context to the function which is a type of gin.Context then we docontext.BindJSON(&championReq) this means we are mapping the JSON we got in the request body. You may be wondering why we use &championReq . It means we are using the address of the championReq variable. In Go language, we can use pointers. ( I will explain it in another post).

Next, we do some checks if the champion name is available and the champion quote is available. If not we return an error bad request. If there is no issue we will check champion is already on the map.

you can see we are using _ it because in Go we can’t initialize variables if we are not going to use them. So _ means a blank identifier because we are not going to use the value we get from the key championReq.Name we just want to throw an error if the champion already exists on the map.

So if our request passes the two checks above we will add the champion to the map. Let’s check it in postman.

Returned with 400 Bad request
Returned with 201 created
Returned with 409 Conflict
GET request returned with 200 success

PUT Request

Let’s now try to create a put request to update the champion quote.

As you can see we created a new function named as UpdateChampion() what we do here is the same as the POST request we bind JSON from the request to the chamiponReq variable and do some checks to make sure that the values from the request are not null and there is already a champion availble in the map. If the champion is available on the map we are updating the quote of the champion. Let's check that in postman.

Reutrned with 201 status code
Returned with 200 status code

When we try to get the champion Akshan we can see it is updated

DELETE Request

Let’s now try to create a DELETE request to remove the champion from the map.

As you can see I added a DeleteChampion() function and you can see I used delete(champions,champion) it means that get the map and delete the key in the map. if there is no such key this doesn't throw an error so we can use it in this way. Let's see what happens using postman.

Returned with 200 status code
Returned with 404 status code

As you can see after deleting the champion we try to get the champion and it returned with a 404 not found status.

This is the end of this creating simple REST APIs using Gin and Go. You can find the source code below.

--

--