Gin HTTP 框架

Gin 框架的核心能力:路由分组、中间件链、JSON 绑定、路径参数,以及与标准库的选择依据。

#type / resource #status / growing #tech / dev / backend #resource / go

[!info] related notes

Gin HTTP 框架

什么时候用 Gin 而不是标准库

Go 1.22+ 的标准库已经支持方法路由(GET /path),但 Gin 额外提供:

能力标准库Gin
路由分组手动拼r.Group("/api/v1")
中间件链手动套r.Use(middleware)
JSON 绑定json.NewDecoderc.ShouldBindJSON(&req)
参数验证自己写binding:"required" 标签
路径参数r.PathValue("id")c.Param("id")

对于路由多(20+)、需要中间件的项目,Gin 减少样板代码。简单服务用标准库就够。

路由分组

r := gin.Default()

// 公开路由
auth := r.Group("/api/v1/auth")
{
    auth.POST("/register", handler.Register)
    auth.POST("/login", handler.Login)
}

// 需要认证的路由
protected := r.Group("/api/v1")
protected.Use(authMiddleware)
{
    protected.GET("/profile", handler.GetProfile)
    protected.POST("/consultation", handler.CreateSession)
}

分组的好处:中间件只作用于该分组。

中间件

func authMiddleware(jwtConfig auth.JWTConfig) gin.HandlerFunc {
    return func(c *gin.Context) {
        token := strings.TrimPrefix(c.GetHeader("Authorization"), "Bearer ")
        claims, err := auth.Validate(jwtConfig, token)
        if err != nil {
            c.JSON(401, gin.H{"error": "unauthorized"})
            c.Abort()
            return
        }
        c.Set("user_id", claims.UserID.String())
        c.Next()
    }
}
  • c.Abort() 阻止后续处理
  • c.Set() / c.Get() 在 context 中传递数据

JSON 绑定

type LoginRequest struct {
    Email    string `json:"email" binding:"required,email"`
    Password string `json:"password" binding:"required,min=6"`
}

func (h *Handler) Login(c *gin.Context) {
    var req LoginRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }
}

常见错误

CORS 中间件忘记处理 OPTIONS

if c.Request.Method == "OPTIONS" {
    c.AbortWithStatus(204)
    return
}

Handler 里直接操作数据库

Handler 只做协议转换,业务逻辑和数据操作分别在 service 和 repository。

创建于 2026/6/25 更新于 2026/6/25