批量创建是我们常常遇到的需求,不熟悉的话容易在这花费过多时间,有必要聊一聊postman如何传递数组参数和golang如何绑定前端传递的对象数组

1. postman如何发送数组参数

POST请求的Content-Type如果是application/json的话,传递数组是很容易的,使用[{...}, {...}]传即可。如果是
form-datax-www-form-urlencoded则需要xxx[]来表示参数是数组,postman中的示例如下图
image.png

2. gin中接收数组参数

既然前端传递的是数组,自然的我们想到用slice来接收,因此,创建一个拥有slice字段的结构体,并用form标签和c.ShouldBind来绑定
由文档中对c.ShouldBind的说明可知它是通过Content-Type的类型来进行相应绑定的,所以后端不用关心请求的Content-Type

  1. func (c *Context) ShouldBind(obj interface{}) error
  2. /*
  3. ShouldBind checks the Content-Type to select a binding engine automatically, Depending the "Content-Type" header different bindings are used:
  4. "application/json" --> JSON binding
  5. "application/xml" --> XML binding
  6. otherwise --> returns an error It parses the request's body as JSON
  7. if Content-Type == "application/json" using JSON or XML as a JSON input.
  8. It decodes the json payload into the struct specified as a pointer.
  9. Like c.Bind() but this method does not set the response status code to 400
  10. and abort if the json is not valid.
  11. */
  1. type CreateUserRequest struct {
  2. Username string `form:"username" binding:"required,max=20"`
  3. Age string `form:"age" binding:"gt=0"`
  4. }
  5. type BatchCreateUserRequest struct {
  6. Data []CreatePictureRequest `form:"data[]" binding:"required"`
  7. }
  1. func (u User) BatchCreate(c *gin.Context) {
  2. var param logic.BatchCreateUserRequest
  3. err := c.ShouldBind(&param)
  4. }

但是!!! 这样也只能校验到BatchCreateUserRequest,因为gin是无法校验带有**form**标签的嵌套结构体的,因此,我们还要对嵌套结构体进行校验,在BatchCreate中添加如下代码:

  1. func (u User) BatchCreate(c *gin.Context) {
  2. var param logic.BatchCreateUserRequest
  3. err := c.ShouldBind(&param)
  4. if err != nil {
  5. ...
  6. }
  7. // 校验嵌套结构体
  8. err = c.ShouldBind(param.Data)
  9. if err != nil {
  10. ...
  11. }
  12. }

3. 总结

  • Content-Type是json,参数使用[{...},{...}],如果是form-datax-www-urlencoded,参数使用data[]类似格式表示
  • 后端创建带form标签的内含slice字段的结构体,gin直接使用c.ShouldBind(&param)绑定