Gin 绑定 Query 参数踩坑记:为什么我的 json 标签不生效?
背景在使用 Gin 开发 RESTful API 时我们经常需要从 URL 的查询字符串Query String中获取参数比如 GET /api/search?keywordginpage1。Gin 提供了便捷的绑定方法但如果你和我一样习惯性地给结构体字段打上 json 标签然后调用 c.ShouldBindQuery()那么等待你的很可能是——所有字段都是零值没有任何错误提示。错误场景再现假设你要写一个搜索接口接收 keyword、page、limit 三个查询参数。你写了如下代码typeSearchRequeststruct{Keywordstringjson:keyword binding:requiredPageintjson:pageLimitintjson:limit}funcSearchHandler(c*gin.Context){varreq SearchRequestiferr:c.ShouldBindQuery(req);err!nil{c.JSON(400,gin.H{error:err.Error()})return}// 业务逻辑...c.JSON(200,req)}请求 URLGET /search?keywordgolangpage2limit10服务端实际解析结果是{keyword:,page:0,limit:0}原因分析Gin 的绑定引擎依赖结构体字段上的 form 标签来匹配查询参数名而不是 json 标签。ShouldBindQuery 内部使用的是 form 标签进行映射。只有像 ShouldBindJSON 这样的方法才会使用 json 标签。当你只写了 json 标签时Gin 找不到对应的字段名于是忽略了这些字段导致零值。而且因为绑定过程没有失败只是没匹配到ShouldBindQuery 返回的 err 为 nil所以你不会收到任何错误提示——这才是最坑的地方。解决方案typeSearchRequeststruct{Keywordstringform:keyword binding:requiredPageintform:page,default1Limitintform:limit,default20}这样 ShouldBindQuery 就能正确解析了。同时你可以保留 json 标签如果需要返回 JSON 时使用两者可以共存typeSearchRequeststruct{Keywordstringform:keyword json:keyword binding:requiredPageintform:page json:pageLimitintform:limit json:limit}