Go with Gin 🍺
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 holdgin.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 quotefunc 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 pathspublicRoutes := 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 thehttp.Response
that a normalhttp.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 thistype 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 champion
with 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 ofchampion
from the map or a "zero value" (in this case the empty string)ok
will receive a bool that will be set totrue
ifchampion
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.
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.
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.
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.
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.