CRUD API with Go and PostgreSQL
Tags: go, beginners, api, postgres
Published: 2022-10-29 13:28:47


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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fsx7kde629y6disxqorr.png)
* **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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scenbaubuiotrhv6k201.png)

## 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")
}

```
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
}
```
### 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
		}
	}
}
```
### 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"`
}
```
`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{})
}
```
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
}
```
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)
}
```
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))
}
```
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](https://github.com/chetansj27/crud-go)
Below are screenshots of application.
####Add User
![Add User](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nf108jqj5ch43xtv23c7.png)
####Get All Users 
![Get All Users](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rr9yipyghbbpbldu2l4q.png)
Happy learning!