批量创建是我们常常遇到的需求,不熟悉的话容易在这花费过多时间,有必要聊一聊postman如何传递数组参数和golang如何绑定前端传递的对象数组
1. postman如何发送数组参数
POST请求的Content-Type如果是application/json的话,传递数组是很容易的,使用[{...}, {...}]
传即可。如果是form-data
和 x-www-form-urlencoded
则需要xxx[]
来表示参数是数组,postman中的示例如下图
2. gin中接收数组参数
既然前端传递的是数组,自然的我们想到用slice来接收,因此,创建一个拥有slice字段的结构体,并用form
标签和c.ShouldBind
来绑定
由文档中对c.ShouldBind的说明可知它是通过Content-Type的类型来进行相应绑定的,所以后端不用关心请求的Content-Type
func (c *Context) ShouldBind(obj interface{}) error
/*
ShouldBind checks the Content-Type to select a binding engine automatically, Depending the "Content-Type" header different bindings are used:
"application/json" --> JSON binding
"application/xml" --> XML binding
otherwise --> returns an error It parses the request's body as JSON
if Content-Type == "application/json" using JSON or XML as a JSON input.
It decodes the json payload into the struct specified as a pointer.
Like c.Bind() but this method does not set the response status code to 400
and abort if the json is not valid.
*/
type CreateUserRequest struct {
Username string `form:"username" binding:"required,max=20"`
Age string `form:"age" binding:"gt=0"`
}
type BatchCreateUserRequest struct {
Data []CreatePictureRequest `form:"data[]" binding:"required"`
}
func (u User) BatchCreate(c *gin.Context) {
var param logic.BatchCreateUserRequest
err := c.ShouldBind(¶m)
}
但是!!! 这样也只能校验到BatchCreateUserRequest
,因为gin是无法校验带有**form**
标签的嵌套结构体的,因此,我们还要对嵌套结构体进行校验,在BatchCreate
中添加如下代码:
func (u User) BatchCreate(c *gin.Context) {
var param logic.BatchCreateUserRequest
err := c.ShouldBind(¶m)
if err != nil {
...
}
// 校验嵌套结构体
err = c.ShouldBind(param.Data)
if err != nil {
...
}
}
3. 总结
- Content-Type是json,参数使用
[{...},{...}]
,如果是form-data
和x-www-urlencoded
,参数使用data[]
类似格式表示 - 后端创建带
form
标签的内含slice字段的结构体,gin直接使用c.ShouldBind(¶m)
绑定