参数校验必须显式进行:body需用validator/v10结构体校验,query/path需手动类型转换与范围检查,错误须结构化返回,且校验逻辑应封装复用。

直接用 c.BodyParser 或 c.Query 拿到值后不做校验就往下走,等于把参数合法性交给前端保证——线上出问题时第一个被问责的就是你。
Body 参数必须显式解析 + 校验结构体
Fiber 不会自动反序列化 JSON body,也不会自动触发字段校验。只写 c.BodyParser(&user) 只完成了解析,user 里字段哪怕全是空字符串或负数,也照常进业务逻辑。
- 必须搭配
validator/v10使用:定义 struct 时用validatetag(如validate:"required,email"),再手动调validate.Struct(user) -
required对*string无效——它检查指针是否为 nil,不检查解引用后是否为空;要校验非空值,得用required_if或手动判*user.Email != "" - 嵌套结构体(如
User.Profile)必须加validate:"dive",否则内层字段完全不参与校验 - 时间字段别直接用
time.Time接字符串;先声明为string,再在自定义校验函数里按"2006-01-02"解析并判断
Query 和 Path 参数不能靠自动绑定
c.Query("page") 和 c.Params("id") 返回的全是 string,不做类型转换和范围检查就传给数据库或分页逻辑,极易 panic 或越界。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 数字类 query(如
page、size)必须用strconv.ParseInt(v, 10, 64),且判断err != nil;别用strconv.Atoi——它对超大数会溢出 - 布尔 query(如
?active=true)用strconv.ParseBool,别用字符串比对,否则"1"、"on"等非标准值会漏判 - Path 参数(如
/users/:id)同样要转类型:id, err := strconv.ParseUint(c.Params("id"), 10, 64),失败就立刻返回 400 - 数组型 query(如
?tag=go&tag=web)用c.Queries()拿 map,再遍历校验每个值,不能只取第一个
错误响应必须结构化,别直接返回原始 err
validator 默认错误是扁平字符串,比如 "Key: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tag",前端根本没法定位哪个字段错了。
- 用
err.(validator.ValidationErrors)类型断言,遍历每条错误,提取Field()、Tag()、Value()生成结构化错误对象 - 避免在 struct 上同时写
json:",omitempty"和validate:"required"——前者让空值跳过反序列化,后者因字段未赋值而报错,但你分不清是没传还是传了空串 - 自定义规则(如手机号号段、密码强度)必须提前注册到 validator 实例,不能只写函数体
- 所有校验失败统一返回
c.Status(400).JSON(map[string]interface{}{"errors": errs}),字段名与请求体保持一致
最容易被忽略的是:query 和 path 参数的校验逻辑往往散落在 handler 里,没人维护、不复用、改一处漏十处。建议把常用参数(如分页、排序、ID)封装成可复用的校验函数,接收 *fiber.Ctx 并返回结构体或 error,而不是每次重复写 ParseInt + if err != nil。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










