前言
两年前开始关注 Go,那个时候 Go 的相关学习资料对我来说还比较高深(手动狗头,哈哈哈哈),之前不是搞了个 Leanote 的部署么,发现这个项目是用 Go 写的。在部署过程中发现这个项目居然不用像 Python 一样配置依赖,我就知道,这一天来了。所以就想接触一下 Golang。根据个人需求,先从一个 Web Api 开始,这里使用的是 Gin。以备后查。
开发环境
信息 | 说明 |
---|---|
操作系统版本 | Microsoft Windows 10 专业工作站 10.0.19042 64位 |
开发工具 | Visual Studio Code |
Go 版本 | go version go1.17.5 windows/amd64 |
MinGW64 版本 | gcc version 8.1.0 (x86_64-win32-seh-rev0, Built by MinGW-W64 project) |
开发经过
前面安装 Go
和 MinGW64
的懵逼经历就不聊了,具体分享下怎么搭建基于 Gin
的多文件路由拆分。
Step 1 创建项目文件夹
用的是 Git Bash
所以可以用 Linux
上的命令
mkdir Project
cd Project
# 我的理解是初始化项目, 把 Project 文件夹设为运行路径
# 不然, 会直接使用 GOPATH 作为运行路径
go mod init Project
# 然后就会生成一个 go.mod 文件
# 自己装了 vim 所以可以用 vim 命令
vim go.mod
# 就可以看到里面的信息
module Project
go 1.17
嗯,没啥特别的
Step 2 创建文件目录
cd Project
# 创建入口文件
echo "package main" > main.go
# 创建 App 文件夹
# 个人习惯把入口文件单独放在最外面, 项目放在 App 里
mkdir App
# 创建 App.go, 目的是使整个 App 变成一个包(package)
echo "package App" > App/App.go
# -- 创建路由管理文件
mkdir App/Routers
echo "package Routers" > App/Routers/Router.go
# -- 创建接口文件夹
mkdir App/Interfaces
# -- 创建接口路由文件
echo "package Interfaces" > App/Interfaces/Router.go
# ---- 创建示例接口文件夹
mkdir App/Interfaces/Demo
# ---- 创建示例接口
echo "package Demo" > App/Interfaces/Demo/Demo.go
需要注意的是,同一个包(文件夹)内的文件声明需要相同,比如
Demo
里除了Demo.go
以外还要新增一个Test.go
,那么它的package
也要声明为Demo
。
搞完之后的文件目录如下:
Project
┣━ App
┃ ┣━ Interfaces
┃ ┃ ┣━ Demo
┃ ┃ ┃ ┗━ Demo.go
┃ ┃ ┗━ Router.go
┃ ┣━ Routers
┃ ┃ ┗━ Routers.go
┃ ┗━ App.go
┣━ go.mod
┗━ main.go
Step 3 将包(文件夹)添加到 go.mod 里
go get ./App/
go get ./App/Interfaces/
go get ./App/Interfaces/Demo/
go get ./App/Routers/
有几个就搞几个
Step 4 开始写代码
Project/App/Routers/Routers.go
这个是整个接口路由注册的代码
package Routers
// 引入 Gin
import "github.com/gin-gonic/gin"
type Option func(*gin.Engine)
var options = []Option{}
// 注册路由配置
func Include(opts ...Option) {
options = append(options, opts...)
}
// 初始化
func Init() *gin.Engine {
resObj := gin.New()
for _, opt := range options {
opt(resObj)
}
return resObj
}
Project/App/Interfaces/Demo/Demo.go
这里是实际接口执行的代码
package Demo
import "github.com/gin-gonic/gin"
func Test(context *gin.Context) {
context.JSON(200, gin.H{"message": "测试成功"})
}
Project/App/Interfaces/Router.go
这里是实际接口路由的代码
package Interfaces
import (
"Project/App/Interfaces/Demo"
"github.com/gin-gonic/gin"
)
func Routers(engine *gin.Engine) {
// 当前接口的路由, 子接口可以往下写
engine.GET("/Demo", Demo.Test)
}
Project/main.go
整个项目的入口代码
package main
import (
"Project/App/Interfaces"
"Project/App/Routers"
"fmt"
)
func main() {
// 加载路由
Routers.Include(Interfaces.Routers)
// 初始化路由
resObj := Routers.Init()
// 绑定 5000 端口
if err := resObj.Run(":5000"); err != nil {
fmt.Println("系统启动失败, 错误信息: %v\n", err)
}
}
至此,此次 Demo 的全部代码已经写完了
Step 5 运行代码
cd Project
go run main.go
刚写完的时候,由于没有引入 github.com/gin-gonic/gin
,所以会提示
main.go:5:2: package Project/Routers is not in GOROOT (C:\Program Files\Go\src\Project\Routers)
App\Interfaces\Demo\Demo.go:3:8: no required module provides package github.com/gin-gonic/gin; to add it:
go get github.com/gin-gonic/gin
按提示 go get github.com/gin-gonic/gin
引入即可
$ go get github.com/gin-gonic/gin
返回。如果是第一次使用 Gin
,则还需要稍等一下自动下载这个包
go get: added github.com/gin-contrib/sse v0.1.0
go get: added github.com/gin-gonic/gin v1.7.7
go get: added github.com/go-playground/locales v0.13.0
go get: added github.com/go-playground/universal-translator v0.17.0
go get: added github.com/go-playground/validator/v10 v10.4.1
go get: added github.com/golang/protobuf v1.3.3
go get: added github.com/json-iterator/go v1.1.9
go get: added github.com/leodido/go-urn v1.2.0
go get: added github.com/mattn/go-isatty v0.0.12
go get: added github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421
go get: added github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742
go get: added github.com/ugorji/go/codec v1.1.7
go get: added golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
go get: added golang.org/x/sys v0.0.0-20200116001909-b77594299b42
go get: added gopkg.in/yaml.v2 v2.2.8
再一次运行 go run main.go
返回
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /Note --> Project/App/Interfaces/Demo.Test (1 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :5000
就说明已经编译成功并启动了。
Step 6 查看接口情况
这里用的是 GET
,所以在浏览器就可以看到结果了。
输入 http://localhost:5000/Demo
就可以看到在 Project/App/Interfaces/Demo.go
里的 {"message": "测试成功"}
。说明这个服务就已经搭好了。
Step 7 编译
go build main.go
然后就会在 main.go
同目录中生成一个 main.exe
,这个就是编译好的 Gin Web 服务程序。因为是在 Windows 中开发的,所以理论上可以直接在任何 Windows 设备中运行。实测了 Windows 10(非本机),Windows 7,无需任何依赖,可直接运行。棒!(๑•̀ㅂ•́)و✧
后记
其实还测了一下使用 Go 创建 dll 给 Python 调用。测了一下在 Docker 中部署,由于依赖极少,Docker 的 image 也会比较小。可以节约不少的成本,哈哈哈哈。多线程高并发,等哪天有需求了在搞吧。