Gin Tutorial: Developing a RESTful API using GIN
Published: 2023-09-18 09:39:26

Gin is a web framework written in Golang. It has high performance and good productivity. In this article, we’ll be building a crud API using Gin. This will provide a deeper understanding of the web framework. 
The main topic include:
1.	Create folder for your project
2.	Create Packages for your code
3.	Create the Data structures to handle data (models).
4.	Setting up handler functions using gin 
5.	Use of the MongoDB Go Driver to connect with the MongoDB database
6.	API endpoints and Routing
7.	Testing using Postman

## Pre-Requisites
•	Working knowledge of Golang
•	Have Go installed
•	Some experience working with the MongoDB Go driver. If not please check out this article on the same.
•	A text editor i.e. Visual Studio
•	Postman or a curl tool.

## 1. Create folder for your project
Let’s create a project for the code.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wjfxotnpaz6ojvwf7e8o.png)

•	Go to the directory where you store your Go projects
•	Create a new directory
•	Finally create a module for managing your dependencies by running `go mod init` and include the path in which your module will exist. In this case `github.com/kevin.`
•	Next open the project in your editor. For vs code just type code .
	

## 2. Create Packages for your code
Golang codes are organized into packages. The project structure should adhere to the [go conventions.](https://go.dev/doc/tutorial/create-module#:~:text=Go%20code%20is%20grouped%20into,new%20versions%20of%20the%20module.)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g5jgwg38w779a0uhnkfw.png)


1.	**Controllers**
•	The controllers package contains the logic for handling HTTP requests and managing the application's business logic.
•	Controllers are responsible for parsing incoming HTTP requests, processing data, interacting with models (if necessary), and sending HTTP responses.
•	Controllers act as intermediaries between the incoming HTTP requests (handled by the router) and the application's data models.
•	Example functions in a controller might include handling user registration, login, data retrieval, or any other application-specific logic related to a route.
2.	**Database**
The database package typically contains code responsible for interacting with the application's database system.
3.	**Models**
•	The models package contains data structures and code related to the application's data domain.
•	It defines the data structures that represent the core objects or entities in your application, such as User, Product, Order, etc.
4.	**Routes**
•	The routes package is responsible for defining the application's URL routes and configuring the routing behavior.
•	It often contains code for setting up the router (e.g., using a package like Gorilla Mux) and mapping routes to specific controller functions.
This is just a basic implementation of the MVC pattern to ensure maintainability and separation of concerns. For advanced projects you could include the middleware packages etc.


## 3.	Create the Data structures to handle data (models).
Any API should interact with a database. In this case we’ll implement the MongoDB using the MongoDB Go Driver

1.	In models.go import the `go.mongodb.org/mongo-driver/bson/primitive` package in the MongoDB Go driver provides support for **BSON (Binary JSON)** primitive types. BSON is the binary serialization format used by MongoDB to store and exchange data.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3klgzctip8m8lp1hj65q.png)

2.	Below the import statement declare an album **struct**. Should include the id, artist, title of album and the price.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/64ytckw7khaxgr89azy8.png)

## 4. Setting up handler functions with Gin
Write a handler function to return all the items.
1.	In the controllers.go file import the necessary packages.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s2hkxpfobxig5pjbzvws.png)

2.	Declare a variable 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/njggigikki26trw9j079.png)

We’ve declared a variable called _AlbCollection_ that points to the mongo.Collection as its type.
This variable will hold a reference to a MongoDB collection, which is a place where you can store and query documents (data) in MongoDB. albums is the name of the mongo DB collection.
3.	Next, copy this function below the above.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3h9m90u3vhe8zinyg25.png)

In the above code, you:
•	Write a function called _GetAlbums_ that takes *_gin.Context_ as its parameter.
•	Create a context with a timeout of 100 seconds
•	Use the AlbCollection to find all documents in the collection
•	Create a slice to hold the albums retrieved from the database and handle any errors
•	Loop through the cursor to decode and collect each album and append the decoded album to the albums slice
•	Finally, return the list of albums as a JSON response with an HTTP status of 200 (OK)

## Write a function to post items into the database

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uv2dx7zfc46a5gwyx3dq.png)

In this code, you: 
•	Write a handler function to handle the creation of a new album resource in a web application using the Gin web framework and MongoDB for data storage.
•	In the function, you create a **newAlbum** variable of type models. Album and bind the incoming JSON request body to the **newAlbum** variable
•	Next, you generate a new ObjectID for the album
•	Finally, insert the **newAlbum** into the **AlbCollection **and handle the error if any.

## Write a function to get a single item by ID


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ha1nre1px6atduvi2o2.png)
In this code, you:
•	Write the _GetAlbumByID_ function that is designed to retrieve an album from a MongoDB collection by its unique identifier (ID) and return it as a JSON response.
•	In the function, you first retrieve the albumID from the URL parameter and then you create a context with a timeout of 100 seconds
•	Next, parse the albumID into an ObjectID and handle any arising error.
•	Then declare a variable to store the album data and query the AlbCollection to find the album with the matching ObjectID. Handle the errors if any.
•	Finally, return the found album as a JSON response with an HTTP status of 200 (OK)


## Write a function to modify an album

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m4mxfcbc6s34zkd0e1j4.png)

This function is designed to update an existing album in a MongoDB collection based on the provided album ID and the new album data provided in the JSON request body.
•	First, you retrieve the albumID from the URL parameter and then you create a context with a timeout of 100 seconds
•	Then, you declare a variable **updatedAlbum** to store the updated album data 
•	Bind the incoming JSON request body to the **updatedAlbum** variable and handle the errors if any.
•	Parse the **albumID** into an ObjectID and handle the errors
•	Define a filter to find the album with the specified ObjectID
•	Define an update with the new album data using the `"$set" `operator
•	Update the album in the AlbCollection and handle any errors related to writing documents in the collection.
•	Return a JSON response indicating that the album has been updated

## Write a function to delete an album

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gjnqywb44ecwnbt6bafr.png)
This function deletes an existing album from a MongoDB collection based on the provided album ID. It's likely used as a handler for an HTTP DELETE request to remove an album resource.
•	First, you retrieve the albumID from the URL parameter and then you create a context with a timeout of 100 seconds
•	Parse the _albumID_ into an _ObjectID_ and handle errors if any.
•	Define a filter to find the album with the specified **ObjectID**

•	Delete the album from the AlbCollection and handle any errors related to the deletion.
•	Check if any album was deleted and if no album was deleted (not found), return a not found response
•	Return a JSON response indicating that the album has been deleted


## 5. Write the database logic
In the database.go file first import the following packages.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m4oyl7510f5gnfbqt1yk.png)
Then add the following code:

 ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n1qumaza7xfvy16hmxze.png)

The code above has two functions that provide the logic for connecting to the mongo database and creating a reusable client instance and collection handler for a Go web application using the MongoDB Go driver respectively.
The ConnectDB function establishes a connection to the MongoDB database and returns a client instance.
•	Create a new MongoDB client with the specified server URI and if there's an error, log it and exit the application
•	Create a context with a timeout of 100 seconds for the connection operation.
•	Connect the client to the MongoDB server and if there's an error, log it and exit the application.
•	Finally, print a message to indicate successful connection and return the client instance.

Declare a global variable named **_Client_**, which is of type ***mongo.Client**. It assigns the client instance returned by the **ConnectDB** function to this variable. This allows other parts of your application to use the Client variable to interact with the MongoDB database.
The **OpenCollection** function creates and returns a MongoDB collection handler for the specified collection name.
•	Access the specified collection in the "**gintest**" database using the client.
•	Return the collection handler.

6. API endpoints and Routing
In your router.go file add:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2x4jbznqcbwurpzs275r.png)

In the code above we define the routes and associate them with controller functions in a web application built using the Gin web framework.  
The **UserRoutes** function and takes one parameter, router, which is a pointer to a gin.Engine instance.
It is responsible for defining the application's routes and associating them with the appropriate controller functions.
These route definitions establish the API endpoints for your web application. When a request is made to one of these endpoints, Gin will call the associated controller function from the controllers package, which is where the actual request handling and business logic take place.

Finally in the `main.go` file add the following:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jgl6se97de6ex05pjor1.png)
The code above is the main entry point for a Go web application using the Gin web framework. It sets up the application's HTTP server, configures routes, and starts the server.
•	Create a new _Gin router_ instance
•	Add Gin's built-in **logger** middleware for request logging
•	Configure routes for the application by calling the _UserRoutes_ function
•	Finally, start the HTTP server and listen on `port 8080`

Run the program:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/takymxgxv3m80w1vv8ew.png)

It should display this in the terminal:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5x2g08hnyyiyag6cgvx.png)
**7.Test the API using Postman**
**Create a post request:**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ae2j2ad01yemi57i9ay9.png)

Add the raw JSON data.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g3438kuj4f2bkilbmchk.png)


 
After sending the request the response should be:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v507h5x37qzpgs9s993g.png)
Go ahead and add more data.

**Get all albums**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftrryb22cajzlea9s7fy.png)
The result should be all the albums in the database.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6qp0yl7iaa2aoogzjxgo.png)
**Update an album**
Update the price of one album.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1hux9cmbux1tw3hsea8.png)
The result:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzn0mfvoj424arzwf5k5.png)

**Get album by id**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c6z68ppzzdkni7pqmrud.png)

The result:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jayqsptzqzzo304grpvj.png)

**Delete an album**

It should display:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/34q1ja7swctrx1svxcai.png)

The database:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwpvwkg1o6kzhe0ev8wn.png)

**## Conclusion**

This tutorial took you step by step through building a restful API using Gin framework and eventually testing using **Postman**. To improve your Go skills also check out the [official Gin Documentation.](https://gin-gonic.com/docs/) It contains advanced topics regarding the framework.
For the MongoDB Go Driver check out my other [article](https://dev.to/wafulakevin/integrating-mongodb-in-golang-applications-1ehg) on the same. It has some insightful and easily explained operations in MongoDB.
Note: There are several other Go web frameworks i.e. [Echo](https://github.com/labstack/echo) and [Fiber](https://github.com/gofiber/fiber)