“This is the 10th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

preface

Gin ORM framework using redefines practice, and made a simple query, but I still have a flaw, write all the database configuration in a single file, not fault-tolerant processing, today is the three direction for processing, temporarily didn’t want to good project project architecture, had to write the most content temporarily in a single file, because there is only one interface, And run it using Docker.

Optimizing the configuration file

Create a new config.ini file in the project root directory and type the following I think is necessary:

[server] # debug Release Production mode AppMode = Release HttpPort = :8080 [database] Db = mysql DbHost = ***.***.*** DbPort = 3306 DbUser = ***** DbPassWord = ********* DbName = ********Copy the code

An error occurred in the optimization framework

In order to better deal with the content of the interface, handle related errors and unify the interface specification, the content is a little too much, create a new folder global, and then create a new folder golab.go, enter the following content:

Package global import ("net/ HTTP ""github.com/gin-gonic/gin") //Result expose type Result struct {Ctx *gin.Context} //ResultCont returns the following result: Msg string 'json:" Msg "' // Prompt message Data interface{} 'json:" Data "' Func NewResult(CTX *gin.Context) *Result {return &Result{CTX: Func (r *Result) Success(data interface{}) {if data == nil {data = gin.H{}} res := ResultCont{} Res. Code = 200 res.Data = Data res.Msg = "success!" R.tx.JSON(http.statusok, res)} //Error Error func (r *Result) Error(code int, MSG string, data interface{}) { if data == nil { data = gin.H{} } res := ResultCont{} res.Code = code res.Msg = msg res.Data = data r.Ctx.JSON(http.StatusOK, res) }Copy the code

Other optimization

Added reading environment variables in the startup file, interface normalization:

package main import ( "fmt" "main/global" "github.com/gin-gonic/gin" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" "gopkg.in/ini.v1" ) var db *gorm.DB var HttpPort string var AppMode string type UrlType struct { ID uint `gorm:"primary_key"` Name string UrlLists []UrlList `gorm:"FOREIGNKEY:TypeID; ASSOCIATION_FOREIGNKEY:ID" '} type UrlList struct {ID uint 'gorm:"primary_key"' TypeID uint // Default foreign key, User Id Name string URL string} type config struct {App string} func init() { err := ini.Load("config.ini") if err ! Println(" Config file read error, Please check file path :", Err)} // Read item run config HttpPort = file.section ("server").key ("HttpPort").string () AppMode = File.section ("server").key ("AppMode").string () // Read data config DBUser := file.section ("database").key (" DBUser ").string () Password := file.Section("database").Key("DbPassWord").String() Host := file.Section("database").Key("DbHost").String() Port := file.Section("database").Key("DbPort").MustInt(3306) Db := file.Section("database").Key("DbName").String() connArgs := fmt.Sprintf("%s:%s@(%s:%d)/%s? Charset =utf8&parseTime=True&loc=Local", DBUser, Password, Host, Port, Db) err = gorm.Open("mysql", connArgs) if err ! = nil {panic(err)} db.singularTable (true) // Remove s db.automigrate (&UrlList{}, &urlType {}) // Automatic transfer} func main() {r := gin.Default() r.et ("/ping", func(c *gin.Context) {c.son (200, gin.H{ "message": "pong", }) }) defer db.Close() r.GET("/index", func(c *gin.Context) { var list []UrlType db.Debug().Preload("UrlLists").Find(&list) result := global.NewResult(c) result.Success(list) }) gin.SetMode(AppMode) r.Run(HttpPort) }Copy the code

Now look at what the interface returns:

Very standardized, the successful interface has code, MSG, data three major

DockerFile write

Golang is a compiled language. We can use multiple compilations to optimize image size. First compile a base image, and then put the compiled binary file into another image to run the package. Create a new file named Dockerfile in the project root directory, note the exposed port number, and type the following:

## # ---------- building ---------- ## # build with this image FROM Golang :alpine AS Builder # # copy all project files to the root folder of the image. Set the package download source, ENV GO111MODULE=on GOPROXY=https://goproxy.cn # RUN go mod download RUN go build-o My_gin_web. ## # ---------- run ---------- ## # change an image FROM alpine:latest # use the same WORKDIR /build/ # copy the compiled files to the directory where the image is running COPY --from=builder /build. # open port EXPOSE 8080 # Run binary ENTRYPOINT ["./my_gin_web"]Copy the code

Then pack the image:

docker build -t my_gin_web:v1 .
Copy the code

Run container:

docker run -d --name my_gin_web  -p 8080:8080  my_gin_web:v1
Copy the code

Docker client can see the completion of the operation:

The interface is normal:

conclusion

Today I slightly optimized the Gin framework details, made Gin images, ran containers, prepared the deployment online environment, and made relevant CI scripts.