Develop And Dockerize/Containerize Go CRUD API

Develop And Dockerize/Containerize Go CRUD API

Welcome to the Article. In this article we are going to create a Go crud API then we will dockerize/containerize it and will push it to the docker hub. we are not going to use any database here instead we'll use just a slice which is similar to an array in other programming languages and the data type of the slice will be a struct.

Prerequisites:

  1. We will need a go language installed on the machine

  2. Docker

  3. VsCode or any other TextEditor

  4. PostMan/ThunderClient Extension on VScode

A] Let's Create Go CRUD API first

i. Create a folder then switch to the folder and open it in VsCode/TextEditor.

$ mkdir go-crud-api
$ cd go-crud-api
$ code .Now open the terminal and initialize the project.

ii. Now let's initialize the Go project.

$ go mod init github.com/pran2711/go-crud-api

iii. For routing, we are going to use gorilla/mux. so let's install it.

$ go get github.com/gorilla/mux

iv. Create a file with the name main.go and write the initial code.

package main

func main(){

}

v. let's import some necessary packages for the projects.

import (
    "encoding/json"
    "log"
    "math/rand"
    "net/http"
    "strconv"

    "github.com/gorilla/mux"
)

vi. Now here I'm creating struct for Final Year Project and Student.

type FProject struct {
    ProjectId string   `json:"projectid"`
    Title     string   `json:"title"`
    Branch    string   `json:"branch"`
    Students  *Student `json:"student"`
}

type Student struct {
    FirstName string `json:"fname"`
    LastName  string `json:"lname"`
}

vii. Create a slice using the struct and let's add some data inside it which is called seeding the db.

//slice
var fproject []FProject

func main()  {
    fproject = append(fproject, FProject{ProjectId: "1", Title: "AI Bot", Branch: "CS", Students: &Student{FirstName: "Pranav", LastName: "Thorve"}})
}

viii. Now using the gorilla mux let's create routes for adding, reading, updating and deleting the data and assign the port 9000.

func main() {
    r := mux.NewRouter()

    fproject = append(fproject, FProject{ProjectId: "1", Title: "AI Bot", Branch: "CS", Students: &Student{FirstName: "Pranav", LastName: "Thorve"}})

r.HandleFunc("/", allProjects).Methods("GET")
r.HandleFunc("/getproject/{id}",  getSingleProject).Methods("GET")
r.HandleFunc("/addproject", addProject).Methods("POST")
r.HandleFunc("/updateproject/{id}", updateProject).Methods("PUT")
r.HandleFunc("/deleteproject/{id}", deleteProject).Methods("DELETE")

    log.Fatal(http.ListenAndServe(":9000", r))
}

ix. Now let's create all the functions for the routers one by one.

a. let's create the first function allProjects to get all data from API. To convert the slice data into json we are using the "encoding/json" package.

// get allProjects data
func allProjects(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(fproject)
}

b. Now let's create a function for getting data of a single project. for that, we need to pass an id with a URL while hitting the API. To receive that id we will use mux.Vars For looping over the data we are going to use a for-range loop.

// get Single Candidate info
func getSingleProject(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")

    params := mux.Vars(r)

    for _, project := range fproject {
        if project.ProjectId == params["id"] {
            json.NewEncoder(w).Encode(project)
            return
        }
    }

    json.NewEncoder(w).Encode("No Project Found with Requested Id")
    return
}

c. Third function is for adding the data/project. For adding a project we need to create a variable of type FProject and for ProjectID we are using the "math/random" package.


// add new project
func addProject(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "appication/json")

    var project FProject
    json.NewDecoder(r.Body).Decode(&project)

    project.ProjectId = strconv.Itoa(rand.Intn(100))

    fproject = append(fproject, project)
    json.NewEncoder(w).Encode(fproject)
    return

}

d. Now the most important function is for updating the project data. here for updating we are gonna delete the particular project with the help of the id which is received from the request and then add new data with the same id.

func updateProject(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    params := mux.Vars(r)

    for index, project := range fproject {
        if project.ProjectId == params["id"] {
            fproject = append(fproject[:index], fproject[index+1:]...)

            var project FProject
            json.NewDecoder(r.Body).Decode(&project)
            project.ProjectId = params["id"]

            fproject = append(fproject, project)
            json.NewEncoder(w).Encode(project)
            return
        }
    }
}

e. Last and final function is for deleting the particular project. here also we will use the id received from the request.

func deleteProject(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")

    params := mux.Vars(r)

    for index, project := range fproject {
        if project.ProjectId == params["id"] {
            fproject = append(fproject[:index], fproject[index+1:]...)
            json.NewEncoder(w).Encode(fproject)
            break
        }
    }
}

B] Let's Dockerize the application with the help of Dockerfile. then build the docker file and then run it.

i. The first thing is to create Dockerfile for the project and then write all the necessary code in it.

$ vi Dockerfile
# Base golang image on apline linux
FROM golang:1.16-alpine

# Work directory
WORKDIR /go-crud-api

# Install dependencies
COPY go.mod go.sum ./
RUN go mod download

# Copy all the files
COPY . .

# Start the application
CMD ["go", "run", "main.go"]

# Expose server port
EXPOSE 9000

ii. Now build the image using Dockerfile.

$ docker build -t go-crud-api:latest .

iii. Finally, create a container using an image and test all the routes of API using PostMan or Thunderclient.

$ docker run -itd --name go-crud -p 9000:9000 go-crud-api

iv. For pushing the image to docker hub login with your credentials and push the image.

$ docker login
$ docker push go-crud-api:latest

Conclusion:

The whole project was about the containerization of the Go project. In this project, we successfully created the Go crud api for the final year project data where we can add, delete, read and update the data. Then we created a docker image of the project using Dockerfile and pushed it to the docker public repository docker hub.

Thank You!!!!.

Did you find this article valuable?

Support Pranav Thorve by becoming a sponsor. Any amount is appreciated!