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.NewDecoder | c.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。