fiber 的 c.query() 无法正确解析重复键或嵌套查询参数,应使用 c.queries() 处理多值(如 ?tag=a&tag=b),对 json 结构需手动 json.unmarshal;queryparser 不支持点号嵌套且类型推断不稳定;limit/offset 必须校验,建议硬性限制 limit≤100 并返回 400 错误。

用 fiber.Get 处理查询请求时,别直接解析 URL 参数
Go Fiber 默认不自动解析 query string 中的嵌套结构或数组,比如 ?ids=1&ids=2&sort[name]=asc 这类写法,c.Query("ids") 只会返回最后一个值。真要支持多值或结构化查询参数,得手动调用 c.Queries() 或 c.QueryParser()。
实操建议:
-
c.Queries()返回map[string][]string,适合处理重复键(如?tag=a&tag=b) - 若参数是 JSON 风格结构(如
?filter={"name":"x"}),先c.Query("filter")再json.Unmarshal,别依赖QueryParser—— 它对 URL 编码和类型推断不稳定 - 注意:Fiber 的
QueryParser仅支持扁平结构,遇到user.name这种点号嵌套会失败,不是 bug,是设计限制
数据库查询前必须校验 limit 和 offset
用户能任意改 ?limit=9999999,不加约束会导致全表扫描或内存溢出。Fiber 不提供内置分页校验,这事得自己拦住。
常见错误现象:接口响应超时、PostgreSQL 报 ERROR: out of memory、SQLite 直接 panic。
实操建议:
- 硬性限制
limit最大值(如 100),超出则返回400 Bad Request并附带错误信息"limit must be -
offset值为负数或非数字时,c.Query("offset")返回空字符串,需用strconv.Atoi并检查 error - 如果用 GORM,别在
Find前无条件拼Limit(limit).Offset(offset),先做数值合法性判断
用 context.WithTimeout 包裹数据库调用,否则超时会卡死连接
Fiber 的 c.Context() 是 fasthttp.RequestCtx,它不实现标准库 context.Context 的取消机制。直接传给 db.QueryContext 会导致超时后查询仍在运行,连接池被占满。
实操建议:
- 从
c.Context()派生新 context:ctx, cancel := context.WithTimeout(c.Context(), 5*time.Second) - 务必在 handler 结束前调用
cancel(),否则 goroutine 泄漏 - 不要用
c.Context().Deadline()判断是否超时 —— fasthttp 的 deadline 是服务器级配置,和单次请求无关
返回 JSON 时避免直接 c.JSON(200, data) 吐原始结构体
结构体字段没加 json: tag、含私有字段、或嵌套了 time.Time,会导致序列化出空对象、报错或暴露敏感字段(比如 PasswordHash)。
使用场景:用户列表接口返回 []User,但前端只需要 id、name、created_at。
实操建议:
- 定义专用响应结构体,显式控制字段,例如
type UserResp struct { ID uint `json:"id"` Name string `json:"name"` CreatedAt time.Time `json:"created_at"` } -
time.Time字段务必加json:"xxx,omitempty",否则默认序列化成纳秒级整数,前端解析失败 - 别用
map[string]interface{}动态拼响应 —— 类型不安全,IDE 无法提示,后期加字段易遗漏











