shouldbindjson 更灵活:只返回 error,由开发者自定义错误处理;bindjson 则自动终止请求并返回 400 纯文本响应。

直接上手 Gin 是可行的,但别跳过 go mod 初始化和中间件默认行为这两个关键点——否则你会在调试 404、空 JSON 或 panic 时卡住半天。
为什么 gin.Default() 会悄悄加日志和 recover?
它不是“裸引擎”,而是内置了 gin.Logger() 和 gin.Recovery() 中间件。这意味着:
- 每次请求都会打印一行日志(含状态码、耗时、路径),你没写日志代码也会看到输出
- 如果 handler 里 panic 了(比如 nil pointer dereference),服务不会崩,而是返回 500 并记录堆栈
- 如果你要关闭日志(比如测试或压测),得用
gin.New()手动注册需要的中间件
c.ShouldBindJSON() 和 c.BindJSON() 的区别在哪?
两者都从请求体解析 JSON 到结构体,但错误处理逻辑不同:
-
c.BindJSON():遇到解析失败(如字段类型不匹配、缺少必需字段)会自动终止请求,返回 400,并写入错误响应 -
c.ShouldBindJSON():只做解析,返回error,由你决定怎么处理(比如统一返回 400 + 自定义 message,或忽略某些字段) - 推荐用
ShouldBindJSON(),尤其在需要自定义错误格式或做预校验时
路径参数 :id 和查询参数 ?page=1&size=10 怎么安全取值?
别混用 c.Param() 和 c.Query(),它们来源不同,且默认不校验类型:
-
c.Param("id")取路径段(如/users/123中的123),返回string,需手动转int或uuid.Parse() -
c.Query("page")取 URL 查询参数,也返回string;c.DefaultQuery("page", "1")可设默认值 - 强烈建议用
c.GetInt("page")或c.GetUint("size")—— 它们内部做了strconv转换并返回int和error,避免 panic
路由分组后中间件作用域容易被忽略的细节
r := gin.Default() 下的 r.Group("/api") 不会自动继承父级中间件,除非显式调用 .Use():
- 全局中间件(如鉴权)必须在分组上调用
.Use(authMiddleware),否则该组内所有路由都不生效 - 分组中间件只影响该组及其子分组,不影响其他分组(比如
/health这类公开端点就不该套鉴权) - 多个中间件顺序很重要:
.Use(m1, m2)表示先执行m1,再m2,m1.Next()后才进m2
最常漏掉的是分组中间件注册和参数类型转换——写完接口跑起来没问题,一到真实请求带非数字 id 或缺失字段就 500,其实只是少了一行 if err != nil { ... } 校验。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











