从零开始摸索VUE,配合Golang搭建导航网站(十Gin

「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

前言

上篇主要实践Gin框架ORM使用,做了一个简单的查询,但是还是有点瑕疵,把所有数据库配置写在了一个单文件中,没有容错处理,今天就这三个方向进行处理一下,暂时没想好项目项目架构,只好把大部分内容暂时都写在一个单文件,因为只有一个接口,并且把它使用Docker运行起来。

优化配置文件

在项目根目录新建一个config.ini文件,输入以下我觉得必要的内容:

1
2
3
4
5
6
7
8
9
10
11
12
ini复制代码[server]
# debug 开发模式,release 生产模式
AppMode = release
HttpPort = :8080

[database]
Db = mysql
DbHost = ***.***.***.***
DbPort = 3306
DbUser = *****
DbPassWord = *********
DbName = ********

优化框架报错

为了前端更好的处理接口的内容,处理相关报错,统一下接口规范,内容有点多,新建一个文件夹global,再该文件夹新建一个golab.go,输入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
go复制代码package global

import (
"net/http"

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

//Result 暴露
type Result struct {
Ctx *gin.Context
}

//ResultCont 返回的结果:
type ResultCont struct {
Code int `json:"code"` //提示代码
Msg string `json:"msg"` //提示信息
Data interface{} `json:"data"` //数据
}

//NewResult 创建新返回对象
func NewResult(ctx *gin.Context) *Result {
return &Result{Ctx: ctx}
}

//Success 成功
func (r *Result) Success(data interface{}) {
if data == nil {
data = gin.H{}
}
res := ResultCont{}
res.Code = 200
res.Data = data
res.Msg = "成功!"
r.Ctx.JSON(http.StatusOK, res)
}

//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)
}

其他优化

在启动文件新增了环境变量的读取,接口规范化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
go复制代码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 // 默认外键, 用户Id
Name string
URL string
}

type config struct {
App string
}

func init() {
//配置文件路径
file, err := ini.Load("config.ini")
if err != nil {
fmt.Println("配置文件读取错误,请检查文件路径:", err)
}
//读取项目运行配置
HttpPort = file.Section("server").Key("HttpPort").String()
AppMode = file.Section("server").Key("AppMode").String()
//读取数据配置
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)
//创建一个数据库的连接
db, err = gorm.Open("mysql", connArgs)
if err != nil {
panic(err)
}
db.SingularTable(true) //去掉数据库自动迁移数据名加的s
db.AutoMigrate(&UrlList{}, &UrlType{}) //自动迁移
}

func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(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)
}

现在看看接口返回的内容:

image.png
非常的规范化了,成功的接口有code,msg,data三大部分

DockerFile编写

DockerFile目的就是把项目打包起来,方便项目部署,golang是一个编译型的语言,我们看可以采用多段编译优化镜像大小,先编译使用一个基础镜像,再把编译打包出来的二进制文件,放到另外一个镜像运行打包发布。

在项目根目录新建一个文件名为:Dockerfile,注意暴露的端口号,输入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
ini复制代码##
# ---------- building ----------
##
#编译用这个镜像
FROM golang:alpine AS builder

#设置工作路径
WORKDIR /build

#把项目所有文件复制到镜像的根目录文件夹中
ADD . ./

# 设置Go语言的环境变量,打开Go Module模式。设置包下载源,有利于快速下载包
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn

#下载go.mod里面的包
RUN go mod download

#编译成二进制文件
RUN go build -o my_gin_web .

##
# ---------- run ----------
##
#换一个镜像
FROM alpine:latest

#采用相同的工作目录
WORKDIR /build/

#把编译好的文件复制到到运行镜像的目录下
COPY --from=builder /build .

#打开端口
EXPOSE 8080

#运行二进制文件
ENTRYPOINT ["./my_gin_web"]

然后打包镜像:

1
erlang复制代码docker build -t my_gin_web:v1 .

运行容器:

1
css复制代码docker run -d --name my_gin_web  -p 8080:8080  my_gin_web:v1

在docker 客户端就可以看到运行完成:

image.png
接口也正常:
image.png

总结

今天稍微了优化了Gin框架细节,制作gin镜像,运行容器,下篇准备部署线上环境,做一下相关CI脚本。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%