gin 获取表单参数的方法是 c.PostForm("name")
,当 name
这个参数不存在时,会默认返回空字符串 ""
然后问题来了,如果用户 POST 请求 api,在 form 里传入了 name=
这样的数据的话,通过 c.PostForm("name")
也将获取到空字符串 ""
,这就导致程序根本没法区分这个空字符串是因为用户没有指定 name
这个参数,还是将 name
这个参数设定成了空字符串
也许会有人觉得这两者没有区别,但是考虑下面这个 API 的话,两者会截然不同:
请求一个 API,可以更新数据库中指定的一些字段,没有指定的字段则不做任何更新。 在这个 API 中, 用户在 post form 中 指定了 name=
的话意味着将 name 字段清空,设置成 ""
, 而不指定 name 参数的话则意味着不对 name 字段做操作
1
kaifang 2020-08-04 19:54:53 +08:00
gin 自带校验器,你这种情况可以用检验器解决
https://gin-gonic.com/docs/examples/bind-form-data-request-with-custom-struct/ |
2
hakono OP |
3
hakono OP @kaifang 搜了下发现 v,err := c.GetPostForm("name") 可以确认存不存在。但是现在我更倾向使用 Bind 配合校验器来处理输入的数据,请问 gin 自带的校验器有没有方法确认一个参数是否存在?
|
4
panlatent 2020-08-04 20:19:30 +08:00
golang 中的类型默认初始化零值,这种参数解析可以大体分为有值(非 null )和无值( null ),有值又分为非零值和零值,所以基本类型是无法表示这三种状态的, 且 validator 库默认会把零值视为必填参数为空。。
可以借鉴 NullXXX 这种类型,并编写支持 validator 验证 / DB Parse / JSON Marshal/Unmarshal 等方法。 |
5
panlatent 2020-08-04 20:26:00 +08:00
在我的实际使用中, 实体标志( ID 属性)没有使用 null 值的需求,零值就相当于 null,POST 和 PUT 方法会提交需要的所有字段,以字符串属性为例, 不存在某个 string = “” 表示跳过赋值的情况,所以也用不到 NullType ; 对于 PATCH 这种,有时候业务逻辑是不允许某个属性为空的, 这时仍不需要 NullType, 剩下的情况可能就需要 NullString 这种来上场了。
|
6
hakono OP @panlatent 是的,目前是在编写一个 PATCH 的 API,更新字段,可更新的字段可以为空,然后被这 go 的 null,空值问题搞得焦头烂额的。Python,PHP 等动态语言的话可以很轻松通过赋予 null 或 None 判断,Go 就懵了(才刚学 Go )
Gin 虽然有个函数 GetPostForm 可以支持检测存不存在,但既然 gin 有 validator 肯定还是倾向于使用 validator 这样的话一想到要如你所说用 struct 写个 NullableString 就感觉头疼。。。。 |
7
nomansky 2020-08-04 20:44:42 +08:00 1
用指针类型*string
|
9
labulaka521 2020-08-04 20:56:16 +08:00
前段时间遇到过这种问题,某个参数是必填的,但是可选的值包括此类型值的零值,最后把这个类型的值设置为指针类型的方式解决的
gin 的一个例子 https://play.golang.org/p/cnOMvObJ5Kb |
10
lovejoy 2020-08-04 22:04:12 +08:00
也碰到过类似问题,最后发现只能用指针的方式搞。
|
11
vvmint233 2020-08-04 22:24:17 +08:00
那么为什么不让前端把整个数据架构传过来然后一起更新呢, {"a": "1", "b": "2"}, 变更了 b, 整个结构变成了{"a": "1", "b": "3"}, 前端将 a 和 b 一起传过来, 这样就不需要考虑有没有设置空值的问题了, 只需要考虑零值的问题
|