Skip to content

akmamun/gin-boilerplate

Repository files navigation

Go Boilerplate

An API boilerplate written in Golang with Gin Framework and Gorm

Motivation

Write restful API with fast development and developer friendly

Table of Contents

Configuration Manage

ENV Manage

  • Default ENV Configuration Manage from .env. sample file .env.example
# Server Configuration
SECRET=h9wt*pasj6796j##w(w8=xaje8tpi6h*r&hzgrz065u&ed+k2)
DEBUG=True # `False` in Production
ALLOWED_HOSTS=0.0.0.0
SERVER_HOST=0.0.0.0
SERVER_PORT=8000

# Database Configuration
MASTER_DB_NAME=test_pg_go
MASTER_DB_USER=mamun
MASTER_DB_PASSWORD=123
MASTER_DB_HOST=postgres_db
MASTER_DB_PORT=5432
MASTER_DB_LOG_MODE=True # `False` in Production
MASTER_SSL_MODE=disable

REPLICA_DB_NAME=test_pg_go
REPLICA_DB_USER=mamun
REPLICA_DB_PASSWORD=123
REPLICA_DB_HOST=localhost
REPLICA_DB_PORT=5432
REPLICA_DB_LOG_MODE=True # `False` in Production
REPLICA_SSL_MODE=disable
  • Server DEBUG set False in Production
  • Database Logger MASTER_DB_LOG_MODE and REPLICA_DB_LOG_MODE set False in production
  • If ENV Manage from YAML file add a config.yml file and configuration db.go and server.go. See More ENV YAML Configure

Server Configuration

  • Use Gin Web Framework

Database Configuration

  • Use GORM as an ORM
  • Use database MASTER_DB_HOST value set as localhost for local development, and use postgres_db for docker development

PG Admin

  • Check PG Admin on http://0.0.0.0:5050/browser/
  • Login with Credential Email [email protected] Password root
  • Connect Database Host as postgres_db, DB Username and Password as per .env set
  • Note: if not configure .env, default Username mamun and password 123

Installation

Local Setup Instruction

Follow these steps:

  • Copy .env.example as .env and configure necessary values
  • To add all dependencies for a package in your module go get . in the current directory
  • Locally run go run main.go or go build main.go and run ./main
  • Check Application health available on 0.0.0.0:8000/health

Develop Application in Docker with Live Reload

Follow these steps:

Middlewares

  • Use Gin CORSMiddleware
router := gin.New()
router.Use(gin.Logger())
router.Use(gin.Recovery())
router.Use(middleware.CORSMiddleware())

Boilerplate Structure

├── config
│   ├── config.go
│   ├── db.go
│   └── server.go
├── controllers
│   └── example_controller.go
├── docker-compose-dev.yml
├── docker-compose-prod.yml
├── Dockerfile
├── Dockerfile-dev
├── go.mod
├── go.sum
├── helpers
│   ├── response.go
│   └── search.go
├── infra
│   ├── database
│   │   └── database.go
│   └── logger
│       └── logger.go
├── LICENSE
├── main.go
├── Makefile
├── migrations
│   └── migration.go
├── models
│   └── example_model.go
├── README.md
├── repository
│   └── sql_repo.go
├── routers
│   ├── index.go
│   ├── middleware
│   │   └── cors.go
│   └── router.go

Examples

Let's Build an API

  1. models folder add a new file name example_model.go
package models

import (
	"time"
)

type Example struct {
	Id        int        `json:"id"`
	Data      string     `json:"data" binding:"required"`
	CreatedAt *time.Time `json:"created_at,string,omitempty"`
	UpdatedAt *time.Time `json:"updated_at_at,string,omitempty"`
}
// TableName is Database Table Name of this model
func (e *Example) TableName() string {
	return "examples"
}
  1. Add Model to migration
package migrations

import (
	"gin-boilerplate/infra/database"
	"gin-boilerplate/models"
)

// Migrate Add list of model add for migrations
func Migrate() {
	var migrationModels = []interface{}{&models.Example{}}
	err := database.DB.AutoMigrate(migrationModels...)
	if err != nil {
		return
	}
}
  1. controller folder add a file example_controller.go
  • Create API Endpoint
  • Write Database Operation in Repository and use them from controller
package controllers

import (
  "gin-boilerplate/models"
  "gin-boilerplate/repository"
  "github.com/gin-gonic/gin"
  "net/http"
)

func GetData(ctx *gin.Context) {
  var example []*models.Example
  repository.Get(&example)
  ctx.JSON(http.StatusOK, &example)

}
func Create(ctx *gin.Context) {
  example := new(models.Example)
  repository.Save(&example)
  ctx.JSON(http.StatusOK, &example)
}
  1. routers folder add a file example.go
package routers

import (
  "gin-boilerplate/controllers"
  "github.com/gin-gonic/gin"
  "net/http"
)

func RegisterRoutes(route *gin.Engine) {
  route.GET("/health", func(ctx *gin.Context) { ctx.JSON(http.StatusOK, gin.H{"live": "ok"}) })
  //added new
  route.GET("/v1/example/", controllers.GetData)
  route.POST("/v1/example/", controllers.Create)

  //Add All route
  //TestRoutes(route)
}
  • Congratulation, your new endpoint 0.0.0.0:8000/v1/example/

Deployment

Container Development Build

  • Run make build

Container Production Build and Up

  • Run make production

ENV Yaml Configure

database:
  driver: "postgres"
  dbname: "test_pg_go"
  username: "mamun"
  password: "123"
  host: "postgres_db" # use `localhost` for local development
  port: "5432"
  ssl_mode: disable
  log_mode: false

server:
  host: "0.0.0.0"
  port: "8000"
  secret: "secret"
  allow_hosts: "localhost"
  debug: false #use `false` in production
  request:
    timeout: 100
func ServerConfig() string {
viper.SetDefault("server.host", "0.0.0.0")
viper.SetDefault("server.port", "8000")
appServer := fmt.Sprintf("%s:%s", viper.GetString("server.host"), viper.GetString("server.port"))
return appServer
}
func DbConfiguration() string {
	
dbname := viper.GetString("database.dbname")
username := viper.GetString("database.username")
password := viper.GetString("database.password")
host := viper.GetString("database.host")
port := viper.GetString("database.port")
sslMode := viper.GetString("database.ssl_mode")

dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=%s",
host, username, password, dbname, port, sslMode)
return dsn
}

Useful Commands

  • make dev: make dev for development work
  • make build: make build container
  • make production: docker production build and up
  • clean: clean for all clear docker images

Use Packages

  • Viper - Go configuration with fangs.
  • Gorm - The fantastic ORM library for Golang
  • Logger - Structured, pluggable logging for Go.
  • Air - Live reload for Go apps (Docker Development)