Gin 快速开始

1. 安装

1
2
# go get 本质上是 git clone
go get github/gin-gonic/gin

2. 新建项目

1
2
3
mkdir <项目名>
cd <项目名>
go mod init github.com/<账号名>/<模块名>

3. HELLO WORLD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

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

func main() {
// 创建服务器
ginServer := gin.Default()
// 处理请求 (此处使用匿名函数)
ginServer.GET(("/hello"), func(ctx *gin.Context) {
ctx.JSON(200, gin.H{"msg": "hello world"}) // 返回 JSON 数据
})
// 启动服务器
ginServer.Run(":8082")
}
  • ctx 代表当前请求的上下文对象, 包括 Request 和 Response

4. 使用模板传递页面

提前加载静态页面:

1
ginServer.LoadHTMLGlob("./templates/*")

传递 Response 时使用:

1
context.HTML(200, "index.html", gin.H{"name": "小明"})

模板接收参数:

1
<p> 你好, {{.msg}} </p>

5. 加载静态资源

1
2
3
// 第一个参数为 URL前缀
// 第二个参数为 本地路径
ginServer.Static("/static", "./static")

6. 获取 Request 参数

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
// A. 查询参数
ginServer.GET("/user", func(ctx *gin.Context) {
id := ctx.Query("id")
name := ctx.Query("name")
})
// B. 路径参数
ginServer.GET("/user/:id/:name", func(ctx *gin.Context) {
id := ctx.Param("id")
name := ctx.Param("name")
})
// C. Request(JSON) Body
// C.1 原始写法
ginServer.POST("/login", func(ctx *gin.Context) {
data, _ := ctx.GetRawData() // 第二个参数是 err, 此处未处理
m := gin.H{}
json.Unmarshal(data, &m)
ctx.JSON(http.StatusOK, m)
})
// C.2 改进写法
ginServer.POST("/login", func(ctx *gin.Context) {
m := gin.H{}
if err := ctx.BindJSON(&m); err != nil { // 第一部分执行, 第二部分判断
ctx.JSON(http.StatusBadRequest, gin.H{"error": "JSON 解析失败"})
return // 记得终止
}
ctx.JSON(http.StatusOK, m)
})
// D. Form Data
ginServer.POST("/user", func(ctx *gin.Context) {
id := ctx.PostForm("id")
name := ctx.PostForm("name")
})

7. 路由组

目录结构:

1
2
3
4
go_gin/
├── main.go
└── routes/
└── user.go

routes/user.go:

1
2
3
4
5
6
7
8
9
package routes

func RegisterUserRoutes(ginServer *gin.Engine) {
userGroup := ginServer.Group("/user")

userGroup.GET("/add", func(c *gin.Context) {})
userGroup.POST("/login", func(c *gin.Context) {})
userGroup.POST("/logout", func(c *gin.Context) {})
}

main.go:

1
2
3
4
5
6
7
8
9
10
package main

import (
"github.com/dylan-chiu/go_gin/routes" // 需完整
)
func main() {
ginServer := gin.Default()
routes.RegisterUserRoutes(ginServer) // 注册路由
ginServer.Run()
}

8. 特殊路由

1
2
3
4
5
6
7
8
// 重定向
ginServer.GET("baidu", func(ctx *gin.Context) {
ctx.Redirect(http.StatusMovedPermanently, "https://www.baidu.com")
})
// 404
ginServer.NoRoute(func(ctx *gin.Context) {
ctx.HTML(http.StatusNotFound, "404.html", nil)
})

9. 中间件

用法

1
2
3
4
5
6
7
8
func MyMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 这里的代码会在请求处理前执行
c.Next() // 执行后续的所有处理器(包括后续中间件和最终处理函数)
// 这里的代码会在请求处理后执行(后续处理器执行完毕后)
}
}
ginServer.Use(MyMiddleware())

跨域

1
2
3
4
5
6
7
8
9
10
11
12
// a. 允许所有跨域请求 (开发环境)
ginServer.Use(cors.Default())

// b. 自定义配置 (实际常见配置)
ginServer.Use(cors.New(cors.Config{
AllowOrigins: []string{"https://example.com"},
AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE"},
AllowHeaders: []string{"Origin", "Content-Length", "Content-Type"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}))

参考
a. BV1Rd4y1C7A1