Initialize a Go-Web project with Gin framework

Third-party libraries used

  • gin Gin frame
  • viper configuration file management
  • cors cross domain resource request configuration
  • gorm ORM library
  • zap logging

main package

Entry point for Go language programs

main.go text

  1. Use flag to read the configuration file path parameter, the default is in the current directory
  2. Use viper to read the config.ini configuration file to initialize the initial data
  3. Initialize random number seed
  4. Initialize database
  5. Declare launcher mode
  6. Configure startup parameters and start the service
package main

import (
	"flag"
	"log"
	"math/rand"
	"project/dao"
	"project/routers"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
)

var (
	ServiceHost  string
	ServicePort  string
)

func init() {
	var configPath string
	flag.StringVar(&configPath, "config-path", ".", "path to config file")
	flag.Parse()
	viper.SetConfigName("config")   // 设置配置文件名为“config”
	viper.SetConfigType("ini")      // 设置配置文件类型为“ini”
	viper.AddConfigPath(configPath) // 设置在configPath中查找配置文件
	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			// Config file not found; ignore error if desired
			log.Panic("没有找到配置文件")
		} else {
			// Config file was found but another error was produced
			log.Panic("初始化配置出错", err.Error())
		}
	}
	ServiceHost = viper.GetString("service.host")
	ServicePort = viper.GetString("service.port")
	dao.DatabaseUser = viper.GetString("database.user")
	dao.DatabasePwd = viper.GetString("database.pwd")
	dao.DatabaseHost = viper.GetString("database.host")
	dao.DatabasePort = viper.GetString("database.port")
	dao.DatabaseName = viper.GetString("database.name")
}
func main() {
	rand.Seed(time.Now().Unix())
	mode := "release"
	err := dao.InitMySQL()
	if err != nil {
		log.Println("初始化数据失败", err.Error())
		return
	}
	switch mode {
	case "debug":
		gin.SetMode(gin.DebugMode)
	case "release":
		gin.SetMode(gin.ReleaseMode)
	case "test":
		gin.SetMode(gin.TestMode)
	}
	r := routers.SetupRouter()
	s := &http.Server{
		Addr:         ServiceHost + ":" + ServicePort,
		Handler:      r,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}
	err = s.ListenAndServe()
	if err != nil {
		panic(err)
	}
}

package

Usually used in the implementation of the data storage layer, the underlying database access operations can be encapsulated to hide details to simplify database operations

mysql.go text

Use gorm to initialize MySQL database connection

package dao

import (
	"fmt"
	"log"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var (
	Db           *gorm.DB
	DatabaseUser string
	DatabasePwd  string
	DatabaseHost string
	DatabasePort string
	DatabaseName string
)

func InitMySQL() (err error) {
	dsn := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True&loc=Local",
		DatabaseUser, DatabasePwd, DatabaseHost, DatabasePort, DatabaseName)
	Db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Panic("连接数据库失败", err.Error())
	}
	// 测试数据库连接
	err = Db.Exec("SELECT 1").Error
	if err != nil {
		log.Panic("数据库连接失败", err.Error())
	}
	return
}

routers package

Typically used for router configuration, this package contains code that needs to read an HTTP request and send that request to a handler on the appropriate backend, then get the response from the handler

routers.go file

  1. Create logger
  2. Initialize gin engine
  3. Configure cors cross-domain requests
  4. Set a default route, and the data returned when there is no request to the route
package routers

import (
	"net/http"
	"project/controller"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func SetupRouter() *gin.Engine {
	// 创建一个生产级别的日志记录器
	logger, err := zap.NewProduction()
	if err != nil {
		panic(err)
	}
	// 在函数结束后刷新缓冲区
	defer logger.Sync()
	r := gin.Default()
	// 将 logger 存储在 Gin 的中间件中
	r.Use(func(c *gin.Context) {
		c.Set("logger", logger)
		c.Next()
	})

	r.Use(cors.New(cors.Config{
		AllowOrigins:     []string{"*"},
		AllowMethods:     []string{"POST, GET, PUT, DELETE, OPTIONS"},
		AllowHeaders:     []string{"Content-Type, Content-Length"},
		ExposeHeaders:    []string{"Access-Control-Allow-Headers"},
		AllowCredentials: true,
	}))
	r.GET("/first", controller.FirstHandler)

	// 下面有两个配置
	// 如果将前端服务与后端服务同时启动可以设置第一种,将前端打包的文件放到 public 文件夹内
	// 我这里设置的使用 vite 打包,所以就下面这种设置,可以自行更改
	// 当直接访问的时候,就相当于请求"/"路由,就会访问 index.html 页面
	// 设置静态文件服务目录
	r.Static("public", "public")
	r.Static("assets", "public/assets")
	r.GET("/", func(c *gin.Context) {
		c.File("public/index.html")
	})
	r.NoRoute(func(c *gin.Context) {
		c.File("public/index.html")
	})

	// 如果前后端分离模式,可以设置为请求到没有的路由就返回 Not Found
	r.NoRoute(func(c *gin.Context) {
		c.JSON(http.StatusNotFound, gin.H{
			"msg": "Not Found",
		})
	})

	return r
}

controller package

Responsible for maintaining the implementation of business logic, and at the same time calling Dao objects to implement data storage, retrieval and other functions, usually interacting with users and processing related activities

controller.go file

  1. Create an initial default routing function that uses info level logging and returns data
package controller

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func FirstHandler(c *gin.Context) {
	c.MustGet("logger").(*zap.Logger).Info("这是一个Info日志")
	c.JSON(http.StatusOK, gin.H{
		"code": 1,
		"data": "Hello World",
		"msg":  "成功",
	})
}

config.ini file

external configuration file

[service]
host=127.0.0.1
port=8000
[database]
user=root
pwd=123456
host=127.0.0.1
port=3306
name=databasename

build.bat file

Packaging script, no need to modify environment variables every time, no need to manually enter the packaging command
script content: modify the environment variables to arm64 architecture Linux system, package, restore to amd64 architecture Windows system, I use Windows for development here, need to deploy to arm64 architecture Linux on the server, so write it like this, change it as needed

@echo off

go env -w CGO_ENABLED=0
go env -w GOOS=linux
go env -w GOARCH=arm64
go build -ldflags "-w -s"
go env -w CGO_ENABLED=1
go env -w GOOS=windows
go env -w GOARCH=amd64

Guess you like

Origin blog.csdn.net/sywdebug/article/details/132763230