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:
We will need a go language installed on the machine
Docker
VsCode or any other TextEditor
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!!!!.