DEV Community

Cover image for CRUD API with Go and PostgreSQL
Chetan
Chetan

Posted on

CRUD API with Go and PostgreSQL

In this tutorial, we're gonna build a CRUD API using GO and PostgreSQL database. We will use GORM to interact with database. You'll know:

  • How to perform CRUD operations using Go.
  • How to use Gorilla Mux for creating routes.
  • How to perform database operation using GORM.
  • How to marshal and unmarshal the data.

Overview of what we are going to build in this article
Controller Functions

  • GetUsers - This function will list all users.
  • AddUsers - It will accept user's details as request body and save the user in database.
  • GetUserById - This function will accept userId as path variable and will list the user by userId.
  • UpdateUser - It will accepts user's updated details as request body and accept userId as path variable then this will save the updated details in database.
  • DeleteUser - This function will accept userId as path variable and will delete the user from database.

Steps to create project

  • Create a empty folder.
  • Open Command Prompt in that folder and run go mod init modulepath. Modulepath can be the github url of code repository. This command will create a go.mod file to track your code's dependencies. As of now we will see only name of your module and the Go version your code supports.
  • Run this command go get -u gorm.io/gorm and go get -u gorm.io/driver/postgres to install GORM module for interacting with database.
  • Again run this command go get -u github.com/gorilla/mux to install Gorilla Mux for creating routes.
  • Now create the necessary folders. Our project structure should look like this. Folder Structure

Let's start writing the code

Creating Routes:

First we will create the routes for our project. Open users-routes.go. Import gorilla/mux for routes. Import controllers folder from your project. users-routes.go will look like this.

package routes

import (
    "github.com/chetansj27/crud-go/pkg/controllers"
    "github.com/gorilla/mux"
)

var RegisterUserRoutes = func(router *mux.Router) {
    router.HandleFunc("/users", controllers.GetUsers).Methods("GET")
    router.HandleFunc("/users", controllers.AddUsers).Methods("POST")
    router.HandleFunc("/users/{userId}", controllers.GetUserById).Methods("GET")
    router.HandleFunc("/users/{userId}", controllers.UpdateUser).Methods("PUT")
    router.HandleFunc("/users/{userId}", controllers.DeleteUser).Methods("DELETE")
}

Enter fullscreen mode Exit fullscreen mode

When any user hit the GET request on /users path, our route will transfer that request to GetUsers method in controller.
router.HandleFunc("/users", controllers.GetUsers).Methods("GET")
Same will happen for others requests also.

Connecting With Database:

config.go file will be used to connect with database. This file will contains database name, username and password. Below code will be used in config.go

package config

import (
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

var db *gorm.DB

func Connect() {
    dsn := "host=localhost user=username password=password dbname=gorm port=9920 sslmode=disable "
    d, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        panic(err)
    }
    db = d
}
func GetDB() *gorm.DB {
    return db
}
Enter fullscreen mode Exit fullscreen mode

Creating Utility Class:

Now we will open utility.go file. This file will be used for marshalling and unmarshalling the data. Marshalling means encoding Go Objects into JSON and Unmarshalling means converting json(Byte data) into Struct. Below code will handle this.

package utils

import (
    "encoding/json"
    "io/ioutil"
    "net/http"
)

func ParseBody(r *http.Request, x interface{}) {
    if body, err := ioutil.ReadAll(r.Body); err == nil {
        if err := json.Unmarshal([]byte(body), x); err != nil {
            return
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Models and Database Query:

Our user.go file will contains user model and all database queries.
First we will create User struct

type User struct {
    Id      uint64 `gorm:"primaryKey" json:"id"`
    Name    string `json:"name"`
    Email   string `json:"email"`
    Address string `json:"address"`
}
Enter fullscreen mode Exit fullscreen mode

Id is the primary key.
Now we will create a init function for initializing the database.

var db *gorm.DB
func init() {
    config.Connect()
    db = config.GetDB()
    db.AutoMigrate(&User{})
}
Enter fullscreen mode Exit fullscreen mode

In above code we are initializing the database connection which we defined in config.go file.
db.AutoMigrate(&User{}) will create a user table in database where fields of user struct will be converted into columns.

Add User Query

We will create a AddUser function which will take User struct as request body and will return the saved User.

func AddUser(us *User) *User {
    db.Create(&us)
    return us
}
Enter fullscreen mode Exit fullscreen mode

In the same way we can create all function according to our need.

Creating function in controllers:

Controllers are very important for any api. user-routes.go will transfer requests to controller.
We will create a function in controller for adding the user.
user-controllers.go will contain the code for controllers.

Add User

We will AddUser function for creating new user and saving them to database. AddUser function will have two parameters one for returning the response and other for request body.

func AddUser(writer http.ResponseWriter, request *http.Request) {
    addUser := &models.User{}
    utils.ParseBody(request, addUser)
    user := models.AddUser(addUser)
    res, _ := json.Marshal(user)
    writer.Header().Set("Content-Type", "application/json")
    writer.WriteHeader(http.StatusOK)
    writer.Write(res)
}
Enter fullscreen mode Exit fullscreen mode

In above code first we create a addUser variable of User struct type. Then we get the request body from request and parsed it into addUser variable. After that we saved the user in database. Then we marshaled the response. In end we set content-type and statusOk in header and then we write the response into writer. That's how user will added in database.
Same way we can create function for getting the user, updating the user and deleting the user.

Last Step:

After creating all function, now we will configure our main.go file. In this file we will register our routes and define host and port for running the applicatio.

func main() {
    route := mux.NewRouter()
    routes.RegisterUserRoutes(route)
    http.Handle("/", route)
    log.Fatal(http.ListenAndServe("localhost:8182", route))
}
Enter fullscreen mode Exit fullscreen mode

We are all set for running our application. Now open terminal and cd into cmd\main package and run go run main.go this command. Now our application is live at localhost:8182.
For complete code you can visit Github Link
Below are screenshots of application.

Add User

Add User

Get All Users

Get All Users
Happy learning!

Top comments (0)