使用gin开发一个账号注册接口,Facebook/Google以后还会更多,页面都递交到同一个接口,他们递交的JSON数据,除了setting
字段,其他的结构都是一样的,如下:
// facebook
{
"username":"facebook",
"password:"123456",
"setting": {
"create_from":"US",
"is_z":false,
"use":"MD5"
}
}
// Google
{
"username":"google",
"password":"111111",
"setting":{
"enable_two_step":1,
"enable_gmail":1,
"enable_ps":1
}
}
表结构设计如下, 字段 setting 是直接存放了JSON数据格式
CREATE TABLE users (
id int not null auto_increment,
user_name varchar(60) not null,
password char(32) not null,
setting text not null comment 'JSON方式存储'
)
现在想到的一个方式就是,gin定义一个接口
type ReqBase struct {
UserName string `json:"username" form:"user_name"`
Password string `json:"password" form:"password"`
Setting interface{} `json:"setting" form:"setting"`
}
type Req struct {
ReqBase
Setting interface{} `json:"setting" form:"setting"`
}
type ReqFacebook struct {
ReqBase
Setting FbSetting `json:"setting" form:"setting"`
}
type ReqGoogle struct {
ReqBase
Setting GgSetting `json:"setting" form:"setting"`
}
type FbSetting struct {
CreateFrom string `json:"create_from" form:"create_from"`
IsZ string `json:"is_z" form:"is_z"`
Use string `json:"use" form:"use"`
}
type GgSetting struct {
EnableTwoStep int `json:"enable_two_step" form:"enable_two_step"`
EnableGmail int `json:"enable_gmail" form:"enable_gmail"`
EnablePs int `json:"enable_ps" form:"enable_ps"`
}
定义接收的controller
// @Router /api/user/create [post]
// @Summary 注册
// @Tags /api/user
// @Accept json
// @Produce json
// @Param post body dto.ReqFacebook true "参数 json"
// @Param post body dto.ReqGoogle true "参数 json"
// @Success 200 "{"code": 200, "message": "success" }"
func (s *ctrl) Create(ctx *gin.Context) {
reqFb := &dto.ReqFacebook{}
reqGg := &dto.ReqGoogle{}
if errFb := ctx.ShouldBindBodyWith(&reqFb, binding.JSON); errFb == nil {
fmt.Println("facebook")
} else if errGg := ctx.ShouldBindBodyWith(&reqGg, binding.JSON); errGg == nil {
fmt.Println("google")
} else {
fmt.Println("error param")
return
}
req := &dto.Req{}
// logical code ...
convertStruct(reqFb,&req)
saveToDb(&req)
}
存在两个问题:
- 支持同一个接口,可以传入不同结构体的数据,可问生成swag文档的时候,
@Param
只支持一个? 而不能像 @Success
描述一样多个。 - 每次都需要进行一次判断,再转化成规定格式,进入逻辑的处理里面又再次解出。
提问:
- swag 如何可以让参数定义成多个不同类型的
- 关于golang中的结构体的转换,比如他们就只有一个setting字段结构不一样,但实际上是最后以text的方式保存进去。怎么样设计更好。一定非得拆成多个接口吗?不同传入结构体不同的接口?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…