Skip to end of metadata
Go to start of metadata

结构化约束

控制器的输入与输出使用了结构体定义进行约束,结构化维护输入输出数据结构是推荐的方式。例如:

// 账号唯一性检测请求参数,用于前后端交互参数格式约定
type UserApiCheckPassportReq struct {
	Passport string `v:"required#账号不能为空"`
}

虽然只有一个参数,也采用了结构化定义,我们直接查看该结构体便可得知该接口的输入参数格式,而不用进入代码中去分析,从而极大提高维护效率。

结构体转换

结构体转换可以使用GetStruct或者Parse方法,其中Parse同时可以执行数据校验。结构体转换方法的参数都可以给定一个结构体的空指针,内部会自动初始化结构体对象,转换失败(例如提交参数不存在)不会执行初始化。例如:

var (
	data *model.UserApiSignInReq
)
if err := r.Parse(&data); err != nil {
	response.JsonExit(r, 1, err.Error())
}

数据校验

客户端提交的数据都是不可信的,必须要做数据校验。

可以通过给结构体绑定v的标签进行设定校验规则以及定义的错误提示。例如:

// 登录请求参数,用于前后端交互参数格式约定
type UserApiSignInReq struct {
	Passport string `v:"required#账号不能为空"`
	Password string `v:"required#密码不能为空"`
}

数据传参

控制器负责接收、转换、校验、处理请求参数后,将所需的参数传递给调用的service对象方法,而不是直接将Request对象传递给service。例如:

func (a *apiUser) SignIn(r *ghttp.Request) {
	var (
		data *model.UserApiSignInReq
	)
	if err := r.Parse(&data); err != nil {
		response.JsonExit(r, 1, err.Error())
	}
	if err := service.User.SignIn(r.Context(), data.Passport, data.Password); err != nil {
		response.JsonExit(r, 1, err.Error())
	} else {
		response.JsonExit(r, 0, "ok")
	}
}


实现代码

https://github.com/gogf/gf-demos/blob/master/app/api/user.go



Content Menu

  • No labels

6 Comments

  1. // 账号唯一性检测请求参数,用于前后端交互参数格式约定
    type ApiUserCheckPassportReq struct {
    	Passport string `v:"required#账号不能为空"`
    }
    // 这里的命名规则和框架设计/对象封装设计里面的描述有冲突
    // 是应该以业务领域user + 分层名称api,而不是反之
    // 所以该是UserApiCheckPassportReq
    1. 感谢指正,已修改。

  2. xx

    type PaymentOrderApiRechargeReq struct {
        Amount          float64 `v:"min:1#Payment Amount must greater than 0"` //充值金额
        RechargeChannel string  `v:"required"`                                 //渠道名称 eecpay:通宝支付
        PaymentWay      int     `v:"required:min:1"`                           //支付方式 1:信用卡
        CareditCard *PamentCareditCard      //信用卡信息
    }

    像这种结构体内的成员变量也是结构体(CareditCard )的r.Parse(&data)解析不出来的吗?


    1. 应该可以的,不行的话把复现代码提issue。

      1. xx

        已提到码云了

  3. 如果前端传的是JSON,用什么方法解析,tag需要改成`json:xxx吗`