[Part 1] Building and Deploying a REST API with Golang, Clean Architecture, Postgres, and render.com

Hien Luong
3 min readAug 10, 2023

--

Introduction

In this tutorial, we will walk through the process of building a simple REST API using the Go programming language, following the Clean Architecture principles. Our API will use PostgreSQL as the database, and we will deploy it on render.com. To achieve this, we will leverage the following dependencies:

  • Gin: An HTTP web framework
  • Sqlx: A database adapter
  • Envconfig: A tool for managing environment variables
  • Wire: A dependency injection builder

The project is available on this github repository

Database setup

Let’s start by setting up the PostgreSQL database. You have two options: running PostgreSQL in a Docker container or installing it directly on your computer. If you choose Docker, execute the following command to create a container:

docker run --name my-postgres -e POSTGRES_PASSWORD=password -p 5432:5432 -d postgres

Here’s what the command flags do:

--name my-postgres: Assigns the name "my-postgres" to the container.
-e POSTGRES_PASSWORD=password: Sets the PostgreSQL password.
-p 5432:5432: Maps the host's port 5432 to the container's port 5432 for database access.
-d: Runs the container in detached mode.

Once the PostgreSQL container is running, create the database, table, and insert a sample record by opening a terminal session and executing the following commands:

docker exec -it my-postgres psql -U postgres -W

Inside the PostgreSQL prompt:

create database todo_db_development;
\c todo_db_development
CREATE TABLE todos (
id SERIAL PRIMARY KEY,
body VARCHAR(255) NOT NULL,
completed BOOLEAN NOT NULL DEFAULT false
);
INSERT INTO todos (body) VALUES ('Learn golang');

Setting Up Dependencies

Let’s proceed to set up our Go application and install the necessary dependencies. Start by initializing a Go module and installing the required packages:

go mod init github.com/<your_repository>/todo-api
go get github.com/lib/pq
go get github.com/jmoiron/sqlx
go get github.com/gin-gonic/gin
go get github.com/kelseyhightower/envconfig
go get github.com/google/wire

Prepare environment variables

Create a local.env file to manage environment variables for our application:

touch local.env
echo 'DSN="postgres://postgres:password@127.0.0.1/todo_db_development?sslmode=disable"' >> local.env
echo 'GIN_PORT=":7070"' >> local.env

Note: the DSN variable is based on your postgres configuration.

Building the Main Application

Next, create the main.go file to initialize our application and test the PostgreSQL connection:

// cmd/api/main.go
package main

import (
"fmt"
"log"

"github.com/jmoiron/sqlx"
"github.com/kelseyhightower/envconfig"
_ "github.com/lib/pq"
)

type Config struct {
Dsn string `required:"true"`
GinPort string `required:"true" split_words:"true"`
}

func LoadConfig() (*Config, error) {
var c Config
err := envconfig.Process("", &c)
if err != nil {
return nil, fmt.Errorf("failed to load config: %w", err)
}
return &c, nil
}

func NewPostgresDB(conf *Config) (*sqlx.DB, error) {
db, err := sqlx.Connect("postgres", conf.Dsn)
if err != nil {
return nil, err
}
return db, nil
}

func main() {
conf, err := LoadConfig()
if err != nil {
log.Fatalln(err)
}

log.Println("configurations: ", conf)
db, err := NewPostgresDB(conf)
if err != nil {
log.Fatalln(err)
}

log.Println("connected to db with: ", db)
}

Running the Application

Finally, run the main application to test the PostgreSQL connection:

export $(cat local.env | xargs)
go run cmd/api/main.go

If everything is set up correctly, your terminal should display output similar to the following:

2023/08/10 11:09:42 configurations:  &{postgres://postgres:password@127.0.0.1/todo_db_development?sslmode=disable :7070}
2023/08/10 11:09:42 connected to db with: &{0xc000100d00 postgres false 0xc0000789f0}

Conclusion

You’ve finished Part One of our tutorial — nice work!

Let’s summary what we’ve accomplished:

  • Set up PostgreSQL (Docker or local).
  • Installed Gin, Sqlx, Envconfig, and Wire.
  • Established a database connection in Go.

In Part Two, we’ll go deeper. We’ll design the core structure of our clean-arch app and create basic APIs that align with Clean Architecture principles.

Stay tuned for Part Two, where we’ll dive right into building our app’s foundation.

--

--