Building a REST API With Go, Gin Framework, and GORM
Beef up your backend projects
I was looking for a framework to start a backend project to learn and use GORM, which is an ORM library for Go. And Gin caught my attention, I found the documentation really good with examples that help to build a REST API.
I wrote this article as a part of my learning process, so I will share with you how to build a REST API using Gin HTTP Web Framework and GORM as ORM.
Gin Framework
According to its documentation:
Gin is a web framework written in Go (Golang). It features a martini-like API with performance that is up to 40 times faster thanks to httprouter. If you need performance and good productivity, you will love Gin.
Prerequisites
- GO installed
- Gin framework
- GORM
restApi/
grocery/
groceryService.go
model/
groceryModel.go
database.go
main.go
go.mod
go.sum
database.db
We will start defining our model in grocery.go
:
package model import (
"gorm.io/gorm"
) type Grocery struct { gorm.Model
Name string `json:"name"`
Quantity int `json:"quantity"` }
Declaring gorm.Model
above model’s fields will add these fields to the model automatically when you add data to the database:
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
database.go
:
The database function will connect the database. I’m using SQLite, but GORM has drivers for MySQL, PostgreSQL, and SQLServer. The db
variable will open the database.db
file where the data will be stored.
db.AutoMigrate(&Grocery{})
will automatically migrate our schema, and keep it up to date.
groceryService.go
:
GetGroceries
is the function that will get all the groceries stored in the database. We declared the variable groceries
and then we use the variable db to use the method Find, associated with *gorm.DB
and pass the address of groceries as an argument.
Then we use c.JSON
to send the status and the data in groceries as JSON as a response.
GetGrocery
gets you a grocery by its id. It takes the id from the URI. We use the method Where, to get the grocery by its id.
If an id doesn’t exist in the database, a Not Found status and an error message will be sent as a response. If it exists, then the grocery data will be sent as a response.
We make a struct, NewGrocery
, with the fields Name and Quantity and we add binding: required
.
And then in PostGrocery
, we declare a variable grocery with NewGrocery
as the type. If one of the fields is missing or with a typo in the post request, a Bad Request status with an error will be sent as a response.
If everything is correct, like this: {“name”: “Apple”, “quantity”: 5}
. Another variable will be created, newGrocery
, with Grocery as the type.
And its data will be the same as the grocery variable. Then we call the method Create, and pass the address of newGrocery
. And the status and the data will be sent as a response.
In UpdateGrocery
, first, we check if the id passes it in the URI does exist, if it does not, an error and Not Found status will be sent.
If it does exist, a variable with GroceryUpdate
as the type will be created to check the fields, if everything is correct, then we use the method Updates, and send the status with the grocery updated as a response.
In DeleteGrocery
if the id doesn’t exist in the database, an error and a Not Found status will be sent.
If it does exist, the method Delete deletes the grocery. Status and a message will be sent as a response.
main.go
:
In the main function, we called the model.Database()
to initialize the database.
Then we start up our router with:
router := gin.Default()
Now we can use the respective HTTP methods with their URI and functions as arguments. The pattern to use the methods GET, POST, PUT and DELETE is the same:
//method.(URI, function)
router.GET("/groceries", grocery.GetGroceries)
Then we use the method Run and pass the port as an argument. We can use Run without an argument, by default it serves on :8080.
Thank you for taking your time and read this article.
The complete code is here.
References
Want to Connect?You can contact me through Twitter, LinkedIn.Originally published at https://carlosmv.hashnode.dev