Movatterモバイル変換


[0]ホーム

URL:


CodevoWeb

PressESC to close

How to Setup Golang GORM RESTful API Project with Postgres

7Comments51

Golang is a popular and modern language of cloud computing and while it’s a no-brainer that Golang has impressive features that support the needs of microservice architecture, large-scale enterprise applications, and distributed systems.

Nevertheless, Golang was built with web development in mind and has sophisticated web packages that are part of its core library to help developers build high performant web applications.

The Golang community is rapidly growing and many developers are already using Golang for full-stack development and mastering new modules and frameworks that make Golang a strong language for web development.

As of Golang1.15 release, thecore library has been updated with improvements toencoding/json,  net/http,database/sql, anddatabase/sql/driver.

This article will guide you on how you can set up a Golang project with theGORM library and PostgreSQL to build CRUD RESTful API to perform the basicCreate/Get/Update/Delete operations.

Golang GORM RESTful API with Gin Gonic and PostgreSQL Series:

  1. How to Setup Golang GORM RESTful API Project with Postgres
  2. API with Golang + GORM + PostgreSQL: Access & Refresh Tokens
  3. Golang and GORM – User Registration and Email Verification
  4. Forgot/Reset Passwords in Golang with HTML Email
  5. Build a RESTful CRUD API with Golang

Related articles:

How to Setup Golang GORM RESTful API Project with Postgres

Prerequisites

Before going further with this tutorial, you will need:

  • A development environment running Golang.Click here to download the latest version of Go.
  • Familiarity with Golang, SQL, and PostgreSQL queries will be highly beneficial.
  • Have PostgreSQL installed. This is optional since we will be using Docker to run the Postgres server.
  • Have Docker installed on your machine.
  • VSCode as the IDE for Developing Go. I recommend VS Code because it has tools, extensions, and an integrated terminal to make your development process a breeze.

What is an ORM?

Object-Relational Mapping (ORM) is a technique that enables developers to use their native programming paradigm to query and manipulate data from a database.

In layman’s terms, an ORM provides adata mapper pattern to transform data defined in classes or objects to SQL. ORMs also come with CRUD functions already implemented making it easier for developers to perform CRUD operations against the database.

Luckily for us, the Golang community has built a number of developer-friendly Object Relational Mapping libraries to allow Golang developers to use JSONkey:value pair syntax and encoding to map directly to any SQL database like SQLite, MySQL, PostgreSQL, and many more.

Step 1 – Setup the Golang Project

In this step, you will initialize a new Golang project, create a PostgreSQL Docker server, and validate the environment variables with theGolang Viper package.

Initialize the Golang Project

To begin, go into yourGo environment folder and create a new project folder. In this example, you can usegolang-gorm-postgresql . Once the folder is created, navigate to the newly created folder and open it with VS Code using the commands below:

1. mkdir golang-gorm-postgresql2. cd golang-gorm-postgresql3. code .

Running thecode . command will open the project in VS Code. Now open the integrated terminal in VS Code and run the following command to initialize a new Go module to manage our project’s dependencies.

go mod init github.com/YOUR_GITHUB_USERNAME/golang-gorm-postgres

Create a PostgreSQL Docker Container

As part of the prerequisites, you should have Docker installed on your system, which includes Docker Compose by default.

Now create adocker-compose.yml file in the newly-created project to help us manage an instance of PostgreSQL on our machine.

docker-compose.yml

services:  postgres:    image: postgres    container_name: postgres    ports:      - 6500:5432    env_file:      - ./app.env    volumes:      - postgres:/var/lib/postgresql/datavolumes:  postgres:

In the above, we mapped our local port6500 to the Postgres default port5432 inside the container. Mapping the ports will allow us to connect and access our running PostgreSQL server outside the container.

Also, we created a named volume to prevent data loss when deleting the Postgres container.

Now let’s create anapp.env file to contain the credentials required by the Postgres image to configure the PostgreSQL server.

app.env

POSTGRES_HOST=127.0.0.1POSTGRES_USER=postgresPOSTGRES_PASSWORD=password123POSTGRES_DB=golang-gormPOSTGRES_PORT=6500PORT=8000CLIENT_ORIGIN=http://localhost:3000

To avoid accidental pushing of the environment variables to GitHub, create a.gitignore file and add the following code.

.gitignore

# Binaries for programs and plugins*.exe*.exe~*.dll*.so*.dylib# Test binary, built with `go test -c`*.test# Output of the go coverage tool, specifically when used with LiteIDE*.out# Dependency directories (remove the comment below to include it)# vendor/.DS_StoreTODO.mdlogs.txt.idea/secret.mdapp.env

Now start the Postgres Docker container in detached mode with this command:

docker-compose up -d

And stop the running Postgres Docker container with this command:

docker-compose down

Load and Validate the Environment Variables

Next, install theviper package to load the environment variables we added to theapp.env file.

go get github.com/spf13/viper

Create ainitializers/loadEnv.go file and add the following configurations:

initializers/loadEnv.go

package initializersimport ("github.com/spf13/viper")type Config struct {DBHost         string `mapstructure:"POSTGRES_HOST"`DBUserName     string `mapstructure:"POSTGRES_USER"`DBUserPassword string `mapstructure:"POSTGRES_PASSWORD"`DBName         string `mapstructure:"POSTGRES_DB"`DBPort         string `mapstructure:"POSTGRES_PORT"`ServerPort     string `mapstructure:"PORT"`ClientOrigin string `mapstructure:"CLIENT_ORIGIN"`}func LoadConfig(path string) (config Config, err error) {viper.AddConfigPath(path)viper.SetConfigType("env")viper.SetConfigName("app")viper.AutomaticEnv()err = viper.ReadInConfig()if err != nil {return}err = viper.Unmarshal(&config)return}

Let’s evaluate the above code. We defined a struct to contain the allowed environment variables.

Then, we createdLoadConfig() function to load the environment variables from theapp.env file and make them accessible in other files and packages within the application code.

Create a Utility Function to Connect to PostgreSQL

Here, let’s create a helper function to connect the Golang application to the running PostgreSQL server.

To do that, we will need the GORM package and the Postgres driver recommended by GORM. Run this command to install the GORM library and the Postgres driver.

go get -u gorm.io/gorm  go get gorm.io/driver/postgres

You can easily adapt the code in this tutorial to work with any GORM-supported database like:

  • PostgreSQL
  • MySQL
  • SQLite
  • SQL Server

Now create ainitializers/connectDB.go file and add the following code to connect the app to the Postgres server.

initializers/connectDB.go

package initializersimport ("fmt""log""gorm.io/driver/postgres""gorm.io/gorm")var DB *gorm.DBfunc ConnectDB(config *Config) {var err errordsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Shanghai", config.DBHost, config.DBUserName, config.DBUserPassword, config.DBName, config.DBPort)DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})if err != nil {log.Fatal("Failed to connect to the Database")}fmt.Println("? Connected Successfully to the Database")}

TheConnectDB() function will be evoked in theinit() function to create a new connection pool with the Postgres database.

Then, the connection object will be stored in the*gorm.DB struct, which we can use to perform the CRUD operations on the Postgres database.

Step 2 – Data Modeling and Migration with GORM

In this section, you will learn how to build a database model with GORM, install the UUID OSSP plugin and run a migration to push the schema to the PostgreSQL database.

Database migration simply refers to the techniques used by developers to track incremental, and reversible changes in database schemas. You can relate it toGit version control, which allows developers to track changes in a file or source code.

Creating the Database Model with GORM

Now let’s build the database model. A model is a class or struct containing the attributes that represent columns in the database table.

In GORM, we create Go structs that will be transformed into SQL tables. Create amodels/user.model.go with the following Golang struct.

models/user.model.go

package modelsimport ("time""github.com/google/uuid")type User struct {ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4();primary_key"`// ID     uint   `gorm:"primary_key"`Name      string `gorm:"type:varchar(255);not null"`Email     string `gorm:"uniqueIndex;not null"`CreatedAt time.TimeUpdatedAt time.Time}

Quite a lot happening in the above, let’s break it down:

  • We created aUser struct to represent the SQL table in the Postgres database.
  • We usedUUID (Universally Unique Identifier) as the default value for the ID column. Feel free to use incremental numbers if that’s the requirement of your project.
  • Then, we specified tags with backtick annotation on the fields that need modification.
  • Lastly, we added a unique constraint on the Email column to ensure that no two users end up with the same email addresses.

Install the UUID OSSP Module for PostgreSQL

By default, PostgreSQL natively supports the UUID (Universally Unique Identifier) data type but since we are using theuuid_generate_v4() function as a default value on the ID column, we need to manually install the UUID OSSP plugin for it to work.

Theuuid_generate_v4() function will be evoked to generate a UUID value for each record we insert into the database. Most PostgreSQL distributions include the UUID OSSP Module by default but do not activate it.

To install the plugin, we need to run theCREATE EXTENSION command in the Postgres shell.

Now access the bash shell of the running Postgres container with this commanddocker exec -it <container name> bash

docker exec -it postgres bash

Follow these steps to install theUUID OSSP Module:

Step 1: Enter the Postgres shell with this commandpsql -U admin <database name>:

psql -U admin golang-gorm

Step 2: List all the available extensions

select * from pg_available_extensions;
postgresql extensions

After listing the extensions, you will notice theuuid-ossp plugin is available but not installed.

Step 3: Install theuuid-ossp extension

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

Step 4: Exit the Postgres shell with\q .

Step 5: Exit the Postgres Docker container bash shell withexit .

Migrating the Schema with GORM

GORM has a feature toautomatically migrate your schema to the database and keep the schema up to date.

The AutoMigrate function will create tables, missing foreign keys, constraints, columns, and indexes. Also, it will update the existing column’s type if its size, precision, and nullable were changed.

Now, create amigrate/migrate.go file and add the following code:

migrate/migrate.go

package mainimport ("fmt""log""github.com/wpcodevo/golang-gorm-postgres/initializers""github.com/wpcodevo/golang-gorm-postgres/models")func init() {config, err := initializers.LoadConfig(".")if err != nil {log.Fatal("? Could not load environment variables", err)}initializers.ConnectDB(&config)}func main() {initializers.DB.AutoMigrate(&models.User{})fmt.Println("? Migration complete")}

In the above, we loaded the environment variables and created a connection pool to the Postgres database in theinit() function.

Then, we evoked theAutoMigrate() function provided by GORM to create the database migration and push the changes to the database.

Now open the integrated terminal in VS Code and run this command to migrate the schema to the database.

go run migrate/migrate.go

Once the migration is successful, log into pgAdmin with the credentials provided in theapp.env file.

log into the postgres docker container with pgadmin

After logging in, inspect theusers table to see the columns added by the GORM migration tool.

the sql table created by the gorm migrate tool

Step 3 – Create the Golang Server with Gin Gonic

In this step, you will connect to the Postgres database and create a simple Golang server with the Gin Gonic web framework.

Install the Gin Gonic framework and the Air package with the following commands:

go get github.com/gin-gonic/gingo install github.com/cosmtrek/air@latest

TheGolang air package will help us to hot-reload the Gin server upon every file change.

Create amain.go file and add the following code:

package mainimport ("log""net/http""github.com/gin-gonic/gin""github.com/wpcodevo/golang-gorm-postgres/initializers")var (server *gin.Engine)func init() {config, err := initializers.LoadConfig(".")if err != nil {log.Fatal("? Could not load environment variables", err)}initializers.ConnectDB(&config)server = gin.Default()}func main() {config, err := initializers.LoadConfig(".")if err != nil {log.Fatal("? Could not load environment variables", err)}router := server.Group("/api")router.GET("/healthchecker", func(ctx *gin.Context) {message := "Welcome to Golang with Gorm and Postgres"ctx.JSON(http.StatusOK, gin.H{"status": "success", "message": message})})log.Fatal(server.Run(":" + config.ServerPort))}

Let’s evaluate the above code:

  • First, we loaded the environment variables with Viper and created a connection pool to the Postgres database in theinit() function.
  • Then, we created a Gin router and assigned it to theserver variable.
  • Next, we created a new router group. This approach will enable us to group all the routes that have common middlewares or the same path prefix.
  • Next, we defined aGET route to the/api/healthchecker endpoint. You should be familiar with this pattern if you’ve worked withExpress.js,FastAPI,Fastify, orFlask.
    To define a route, we specify the endpoint and a handler. The endpoint is the path to a resource on the server. The handler on the other hand is the function that will be evoked to perform some business logic or return data to the client.
  • Lastly, we evoked theRun method to attach the router to thehttp.Server . This will enable the router to start listening and serving HTTP requests.

Now open the built-in terminal in VS Code and run this command to start the Golang Gin server.

air

The above command will connect the app to the Postgres database and start the server on port8000.

You should see a preview in your terminal like this:

run the air command to start the golang server

Step 4 – Testing the Golang API Server

Once the server is up and running, open any API testing tool and make a request to the/api/healthchecker endpoint.

testing the golang api with postman

Alternatively, openhttp://localhost:8000/api/healthchecker in your browser and you should see the JSON response sent by the Gin server.

testing the api with the browser

Conclusion

With this Golang and Gin Gonic setup example with GORM, PostgreSQL, and Docker-compose, you’ve learned how to set up a Golang project with PostgreSQL, GORM, and Gin Gonic.

Golang, GORM, and Gin Gonic Setup Source Code

You can find the completesource code on my GitHub page

Share Article:

Full-Stack Next.js tRPC App: User Registration & Login Example

Left Arrow

How To Use Prisma with PostgreSQL, SQLite, and MySQL

Right Arrow

7 Comments

  1. Relieyan Ramadhan Hilmanon March 18, 2023

    Thank you for this tutorial, it is concise and helpful!!

    Reply
    • Edemon March 18, 2023

      Am glad you found this tutorial helpful. Cheers and happy coding!

      Reply
  2. Derek Duafaon March 21, 2023

    Thanks, this has been very helpful

    Reply
    • Edemon March 21, 2023

      You’re welcome! I’m glad that the article was helpful for you.

      Reply
  3. Suryaon July 29, 2023

    hello!, when i get github.com/wpcodevo/golang-gorm-postgres/initializers. I have error: Repository not found. And yeah i acces it in the chrome found 404 🙂

    Reply
    • Edemon July 30, 2023

      I’m sorry to hear that you encountered an error with the GitHub repository. Could you please clarify if you were trying to run the project on your machine or if there was something else you were attempting to do? Let me know so that I can assist you further.

      By the way, the correct URL for the repository should be:https://github.com/wpcodevo/golang-gorm-postgres/tree/master/initializers.

      Reply
  4. Daniel Won August 22, 2024

    Very impressive and awesome tutorial!
    Highly recommend it.

    Reply

Leave a ReplyCancel reply

This site is protected by reCAPTCHA and the GooglePrivacy Policy andTerms of Service apply.

This site uses Akismet to reduce spam.Learn how your comment data is processed.

Support Me!

paypal donate button

Recent posts

Categories


[8]ページ先頭

©2009-2025 Movatter.jp