v1.15版本开始,Request请求对象支持通过struct tag的方式为输入对象的属性绑定默认值。默认值的struct tag名称为d(也可以使用default)。

我们来看一个示例以便更好理解。

参数对象定义

type GetListReq struct {
	g.Meta `path:"/" method:"get"`
	Type   string `v:"required#请选择内容模型" dc:"内容模型"`
	Page   int    `v:"min:0#分页号码错误"      dc:"分页号码" d:"1"`
	Size   int    `v:"max:50#分页数量最大50条" dc:"分页数量,最大50" d:"10"`
	Sort   int    `v:"in:0,1,2#排序类型不合法" dc:"排序类型(0:最新, 默认。1:活跃, 2:热度)"`
}
type GetListRes struct {
	Items []Item `dc:"内容列表"`
}

type Item struct {
	Id    int64  `dc:"内容ID"`
	Title string `dc:"内容标题"`
}

这个是一个查询内容列表请求的参数接受对象,其中我们通过d的标签为属性PageSize指定了默认值,当这两个参数不传递时,默认为110,表示分页从第1页开始,每页查询数量为10

参数对象使用

package main

import (
	"context"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

type GetListReq struct {
	g.Meta `path:"/" method:"get"`
	Type   string `v:"required#请选择内容模型" dc:"内容模型"`
	Page   int    `v:"min:0#分页号码错误"      dc:"分页号码" d:"1"`
	Size   int    `v:"max:50#分页数量最大50条" dc:"分页数量,最大50" d:"10"`
	Sort   int    `v:"in:0,1,2#排序类型不合法" dc:"排序类型(0:最新, 默认。1:活跃, 2:热度)"`
}
type GetListRes struct {
	Items []Item `dc:"内容列表"`
}

type Item struct {
	Id    int64  `dc:"内容ID"`
	Title string `dc:"内容标题"`
}

type Controller struct{}

func (Controller) GetList(ctx context.Context, req *GetListReq) (res *GetListRes, err error) {
	g.Log().Info(ctx, req)
	return
}

func main() {
	s := g.Server()
	s.Group("/content", func(group *ghttp.RouterGroup) {
		group.Middleware(ghttp.MiddlewareHandlerResponse)
		group.Bind(&Controller{})
	})
	s.SetPort(8199)
	s.Run()
}

我们访问以下地址,并查看服务端终端输出结果:

http://127.0.0.1:8199/content?type=ask

2023-03-21 21:58:23.058 [INFO] {2883f9c2dc734e170a35c73ea3560b4b} {"Type":"ask","Page":1,"Size":10,"Sort":0}

http://127.0.0.1:8199/content?type=ask&page=

2023-03-21 21:58:32.555 [INFO] {b86e22f9de734e170b35c73edf07859d} {"Type":"ask","Page":1,"Size":10,"Sort":0}

http://127.0.0.1:8199/content?type=ask&page=2

2023-03-21 22:01:02.907 [INFO] {a016c8fa01744e170f35c73e99082f53} {"Type":"ask","Page":2,"Size":10,"Sort":0}

可以看到,当调用端不传递或者传递空的page参数时,服务端都将使用定义的默认值;而当调用端传递具体的page参数时,默认值并不会生效。

注意事项

默认值参数绑定是根据客户端未提交该参数来识别是否启用默认值,如果客户端已经提交了该参数,即便该参数值是空字符串也会被当做客户端已经传递了具体的值,那么服务端数据结构上的默认值标签将不会生效。







Content Menu

  • No labels

11 Comments

  1. 郭强 

    版本 1.16

    问题

    struct 里面 这样设置

    PageSize int `p:"size" d:"10"`

    时,有偶发几率出现参数获取不到的情况,然后自动使用默认值

    改成

    PageSize int `p:"size" d:10`

    即可正常

    而且必须是把 d:10 放在最后面,不然这个设置全都无法识别了

    1. wiki不接受问题反馈,请将代码提交到issue以便确认。

    2. 标签中键对应的值都应该使用双引号包裹,如`id:"999"`,而使用`id:99`根本不起作用,我不明白你改完d为什么还起作用

      1. 请认真审题,不做双引号包裹是有原因的

        1. 你好,我知道你说的前提,但是我感到疑惑的是Golang标签的标准写法问题,不讨论这里的具体问题

  2. 请问d标签支持函数方法吗?比如前端传了字符串,我想用strings.trimSpace在接收参数的时候就去掉首尾空格

  3. bool 类型默认值是不是有bug 默认值是true ,传了false 还是true


    gf version: 2.6.x


    当参数值为"false"正常, 参数值为false就不正常了

    1. 你的代码是什么

  4. 能否设置入参默认值为nil?

    1. 有什么意义呢?

    2. 定义成指针类型即可。但是你默认值nil实在想不到使用场景。