在我们写的绝大部分的 API 代码当中,其实都是需要传递参数的,无论是通过 path、query string 还是 body,在 gin 当中,为我们提供了一系列的 binding 方法让我们可以把这些参数绑定到一个对象中,通过还可以通过 struct tag 来对参数进行校验,不知道到大家曾今是否和遇到过相同的困惑:
我创建/更新接口有时候就仅仅只相差一个 id,我是不是可以复用代码?
是否可以直接用 model 层的 struct 绑定参数?
接下来本文就从这些问题出发,利用 go 的组合特点,介绍一些参数绑定上的小技巧
参数绑定技巧
1. 复用创建/更新时的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// UserParams 用户参数 type UserParams struct { Name string`json:"name" binding:"required"` Password string`json:"password" binding:"required"` }
// CreateUserParams 创建用户 type CreateUserParams struct { UserParams }
// UpdateUserParams 更新用户 type UpdateUserParams struct { UserParams ID uint`json:"id" binding:"required"` }
2. 用 model 层的 struct 绑定参数
如果我们在参数绑定的时候,向上面那样,每个参数单独创建一个绑定,这样在 Model 层创建数据库记录的时候就需要去手动的转换一道了,如果每个都需要这么写,会感觉很麻烦。
这是原本的 user 表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// model/model.go
// Model default model type Model struct { ID uint`json:"id" gorm:"primary_key"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt *time.Time `json:"deleted_at" sql:"index"` }
// model/user.go
// User 用户表 type User struct { Model
Name string`json:"name"` Password string`json:"password"` }
这时我们可以稍微改造一下, 利用 binding:"-" 忽略字段的功能,和 struct 组合,将 api 的参数和 model 关联在一起,减少一些结构体转换的代码
// Model default model type Model struct { ID uint`json:"id" gorm:"primary_key"` CreatedAt time.Time `json:"created_at" binding:"-"` UpdatedAt time.Time `json:"updated_at" binding:"-"` DeletedAt *time.Time `json:"deleted_at" sql:"index" binding:"-"` }
// model/user.go
// User 用户表 type User struct { Model
Name string`json:"name" binding:"required"` Password string`json:"password" binding:"required"` }