Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.7k views
in Technique[技术] by (71.8m points)

gin swag 同一个接口可以传入不同结构体的写法

使用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的方式保存进去。怎么样设计更好。一定非得拆成多个接口吗?不同传入结构体不同的接口?

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...