Skip to content

Latest commit

 

History

History
247 lines (212 loc) · 7.23 KB

README.md

File metadata and controls

247 lines (212 loc) · 7.23 KB

Go Boilerplate

An API boilerplate written in Golang with Gin Framework

Table of Contents

Motivation

Write restful API with fast development and developer friendly

Configuration Manage

  • Manage from config.yml file
  • Use Gin Web Framework
  • Server environment is Gin debug logger, use prod in production and dev in development mode

Server Configuration

server:
  host: "0.0.0.0"
  port: "8000"
  secret: "secret"
  environment: "dev" #debug logger ,use `prod` in production
  request:
    timeout: 100

Database Configuration

  • Use GORM as an ORM. you just need to configure config.yml file according to your setup.
  • Use database host as localhost for local development, if docker use postgres_db
  • Database log_mode is SQL logger, false in production and true in development mode
database:
  driver: "postgres"
  dbname: "test_pg_go"
  username: "mamun"
  password: "123"
  host: "postgres_db" # use "localhost" for local development, `postgres_db` for docker
  port: "5432"
  log_mode: true # SQL logger , false in production

Develop Application in Docker Compose with Live Reload

Follow these steps:

Local Setup Instruction

Follow these steps:

  • Configuration manage from config.yml file
  • 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

Routes

Logging

  • Use logrus - Structured, pluggable logging for Go.
  • INFO 2022-03-12T00:33:32+03:00 Server is starting at 127.0.0.1:8000

Middlewares

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

Boilerplate Structure

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

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)

Code Examples

  • Example contains sample code of different type of example

Lets Build a Endpoint

  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 database

import (
	"gin-boilerplate/models"
)

//Add list of model add for migrations
var migrationModels = []interface{}{&models.Example{}}
  1. controller folder add a file example_controller.go
  • Create API Endpoint
  • Use any syntax of GORM after base.DB, this is wrapper of *gorm.DB
package controllers

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

func (base *Controller) CreateExample(ctx *gin.Context) {
	example := new(models.Example)

	err := ctx.ShouldBindJSON(&example)
	if err != nil {
		logger.Errorf("error: %v", err)
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	err = base.DB.Create(&example).Error
	if err != nil {
		logger.Errorf("error: %v", err)
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusOK, &example)
}
  1. routers folder add a file example.go
package routers

import (
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"gin-boilerplate/controllers"
)


func TestRoutes(route *gin.Engine, db *gorm.DB) {
	ctrl := controllers.Controller{DB: db}
	v1 := route.Group("/v1")
	v1.POST("/example/", ctrl.CreateExample)
}
  1. Finally, register routes to index.go
package routers

import (
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"net/http"
)

//RegisterRoutes add all routing list here automatically get main router
func RegisterRoutes(route *gin.Engine, db *gorm.DB) {
	//Add All route
	TestRoutes(route, db)
}
  • Congratulation, your endpoint created 0.0.0.0:8000/v1/example/

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

Container Development Build

  • Run make build

Container Production Build and Up

  • Run make production