--- tags: [go, golang, gin, Web框架, HTTP] create time: 2026-06-07 15:20 --- # Gin ## 概述 Gin 是 Go 生态中最流行的 Web 框架,以高性能路由和简洁的 API 著称。本文从基础用法到中间件、分组路由,覆盖构建 RESTful API 的核心技能。 ## 正文 ### 安装 ```bash go get -u github.com/gin-gonic/gin ``` ### 快速开始 > [!question] 💭 思考 > 如果让你从零实现一个 HTTP 服务器,需要处理哪些事情?(路由匹配、请求解析、响应格式化……) Gin 封装了这些底层细节,让你专注于业务逻辑: ```go r := gin.Default() // 创建默认引擎(含 Logger + Recovery 中间件) r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{"message": "pong"}) }) r.Run(":8080") // 监听 8080 端口 ``` > [!tip] 💡 Default vs New > - `gin.New()`:纯引擎,无日志和恢复中间件 > - `gin.Default()`:预装 Logger 和 Recovery,生产环境推荐 > - Recovery 中间件会自动 recover panic,避免服务崩溃 ### 路由与参数 #### 路径参数 ```go r.GET("/user/:name", func(c *gin.Context) { name := c.Param("name") // 获取 :name 的值 c.String(200, "Hello %s", name) }) ``` #### Query 参数 ```go r.GET("/search", func(c *gin.Context) { q := c.Query("q", "") // 获取 ?q=xxx,默认值 "" page := c.DefaultQuery("page", "1") // 带默认值 c.JSON(200, gin.H{"query": q, "page": page}) }) ``` #### POST 表单 / JSON ```go type LoginRequest struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` } r.POST("/login", func(c *gin.Context) { var req LoginRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } // 处理登录... c.JSON(200, gin.H{"message": "ok"}) }) ``` > [!warning] ⚠️ 绑定注意事项 > - `ShouldBindJSON` 仅在 Content-Type 为 `application/json` 时生效 > - `binding:"required"` 由内置验证器检查字段是否为空 > - 对于复杂验证需求,建议使用 `github.com/go-playground/validator` ### 中间件 > [!question] 💭 思考 > 如果你的 API 需要对所有请求做日志记录、鉴权、CORS 处理,在每个 handler 里重复写代码合理吗? 中间件是横切关注点的标准解决方案——它在请求到达 handler **之前**和返回响应**之后**执行: ```go // 自定义中间件 func RequestID() gin.HandlerFunc { return func(c *gin.Context) { id := uuid.New().String() c.Set("requestID", id) // 存入上下文 c.Header("X-Request-ID", id) c.Next() // ✅ 必须调用,继续处理后续中间件/handler // 这里可以记录耗时等后处理逻辑 } } // 注册方式 r.Use(RequestID()) // 全局中间件 r.GET("/api", MyHandler) // 受中间件保护 ``` > [!info] ℹ️ 中间件执行顺序 > 先注册的先执行(类似洋葱模型): > ``` > 请求 → Logger → Auth → CORS → Handler > 响应 ← Logger ← Auth ← CORS ← Handler > ``` #### 分组路由 ```go v1 := r.Group("/api/v1") { v1.GET("/users", getUsers) v1.POST("/users", createUser) v1.PUT("/users/:id", updateUser) v1.DELETE("/users/:id", deleteUser) } // 为组注册中间件 authGroup := r.Group("/api", AuthMiddleware()) ``` ### RESTful 完整示例 ```go type User struct { ID int `json:"id"` Name string `json:"name"` Age int `json:"age"` } var users []User func main() { r := gin.Default() r.GET("/users", func(c *gin.Context) { c.JSON(200, users) }) r.GET("/users/:id", func(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) for _, u := range users { if u.ID == id { c.JSON(200, u) return } } c.JSON(404, gin.H{"error": "not found"}) }) r.POST("/users", func(c *gin.Context) { var u User c.ShouldBindJSON(&u) u.ID = len(users) + 1 users = append(users, u) c.JSON(201, u) }) r.Run(":8080") } ``` > [!tip] 💡 性能提示 > - `gin.H` 是 `map[string]interface{}` 的别名,在高频场景中考虑使用自定义结构体替代,减少反射开销 > - 启用 Gzip 压缩:`r.Use(gzip.Gzip(gzip.DefaultCompression))` > - 生产环境建议关闭 Debug 模式:`gin.SetMode(gin.ReleaseMode)` ## 关联笔记 - [[hzh/GolangStar/Go语言框架/gorm]] — Gin + GORM 是全栈开发的经典组合 - [[hzh/GolangStar/Go语言进阶/Context]] — HTTP 请求天然适合用 context 控制超时和取消