Build a simple REST API using Go, MySQL, Gorm, and mux

Go was designed by Google. Golang is influenced by C but with greater simplicity and portability. This article will walk you through building a simple REST API using Go.
About the application
The application is a simple REST API server that will provide endpoints to CRUD operations on Football Ground Booking records.
In order to get this job done, we have to install some dependencies first.
1. Gorilla mux
: For creating routes and HTTP handlers.
go get github.com/gorilla/mux
2. gorm
: An ORM tool for MySQL.
go get github.com/jinzhu/gorm
3.mysql
: The MySQL driver.
go get github.com/go-sql-driver/mysql
Before getting started, first we have to create a database manually. I am using MySQL shell to create a database. Login to MySQL shell and use the following statement to create the database
CREATE DATABASE Football;
Now create a file main.go
in your project directory and start cooking. We want to connect our application to our database:
db, err = gorm.Open(“mysql”, “user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8&parseTime=True”)
NOTE : In order to handle
time.Time
, you need to includeparseTime
as a parameter. (More supported parameters)
Let’s take a look at our main.go
file now:
Let’s test this file
abhi@abhi-Inspiron-N4050:~/$ go build
abhi@abhi-Inspiron-N4050:~/$ go run main.go
2019/07/13 00:49:33 Connection Established
Now, create a simple Booking
struct that features id
, user
, total_members
type Booking struct{
Id int `json:”id”`
User string `json:”user”`
Members int `json:”members”`
}
After creating a struct, it is time to migrate our schema
db.AutoMigrate(&Booking{})
WARNING: AutoMigrate will ONLY create tables, missing columns and missing indexes, and WON’T change existing column’s type or delete unused columns to protect your data.
Create a Web Server
Now we create a web server for handling HTTP requests. For that, I am creating a new function named as handleRequests()
. Under this function create a new instance of a mux
router:
myRouter := mux.NewRouter().StrictSlash(true)
Now run the code by typing go run main.go
abhi@abhi-Inspiron-N4050:~/$ go run main.go
2019/07/13 00:59:54 Connection Established
2019/07/13 00:59:54 Starting development server at http://127.0.0.1:10000/2019/07/13 00:59:54 Quit the server with CONTROL-C.
Then open up http://localhost:10000/
in your browser, and you should see a Welcome to Homepage!
CRUD Operations
In this part, we are going to do CREATE, READ, UPDATE and DELETE operations
- CREATE a new booking
Add the route to the list of routes defined within the handleRequests
function. However, we’ll be adding .Methods("POST")
to the end of our route to specify that we only want to call this function when the incoming request is a HTTP POST
request.
myRouter.HandleFunc(“/new-booking”, createNewBooking).Methods(“POST”)
Let’s create a new function createNewBooking()
which will take a POST request data and create a new booking entry in the DB. But first we have to Unmarshal the JSON data in the request body into a new Booking
struct which can subsequently be appended to the table and for creating a new record we use the following function:
func createNewBooking(w http.ResponseWriter, r *http.Request) {
// get the body of our POST request
// return the string response containing the request body
reqBody, _ := ioutil.ReadAll(r.Body) var booking Booking
json.Unmarshal(reqBody, &booking)
db.Create(&booking) fmt.Println("Endpoint Hit: Creating New Booking")
json.NewEncoder(w).Encode(booking)
}
- READING all bookings
Again add the route to the list of routes defined within the handleRequests
function
myRouter.HandleFunc(“/all-bookings”, returnAllBookings)
Create a new function returnAllBookings()
For getting all records we use db.Find(&bookings)
func returnAllBookings(w http.ResponseWriter, r *http.Request){
bookings := []Booking{}
db.Find(&bookings)
fmt.Println(“Endpoint Hit: returnAllBookings”)
json.NewEncoder(w).Encode(bookings)
}
- Reading Booking detail by their Id
To get this job done we run a loop over all Bookings, if booking.id
equals to the key we pass in the UTL, it returns the booking detail encoded as JSON.
//handleRequests()
myRouter.HandleFunc("/booking/{id}", returnSingleBooking)
func returnSingleBooking(w http.ResponseWriter, r *http.Request){
vars := mux.Vars(r)
key := vars[“id”]
bookings := []Booking{}
db.Find(&bookings) for _, booking := range bookings {
// string to int
s , err:= strconv.Atoi(key)
if err == nil{
if booking.Id == s {
fmt.Println(booking)
fmt.Println(“Endpoint Hit: Booking No:”,key)
json.NewEncoder(w).Encode(booking)
}
}
}
}
Now it’s your turn to build the Update and Delete operation. If you need any help, ask questions in comment section. You can also take help from the following links:
Finally, we completed our first project in Golang. I hope you liked it :)