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

发布于 2022-09-12 22:12:27 字数 2846 浏览 25 评论 0

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

终难遇 2022-09-19 22:12:27

接口这样设计不合适,对客户端与服务端以后的扩展也不好,你可以直接使用增加一个定义类型字段与多个配置.根据typ类型来选取需要取值的结构体

type ReqBase struct {
    UserName  string    `json:"username" form:"user_name" binding:"required"`
    Password  string    `json:"password" form:"password" binding:"required"`
    Typ       string    `json:"typ" form:"typ" binding:"required"` // 类型:google=谷歌,facebook=脸书
    GgSetting FbSetting `json:"google_setting,omitempty" form:"google_setting" `
    FbSetting GgSetting `json:"facebook_setting,omitempty" form:"facebook_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"`
}
{
    "username":"facebook",
    "password:"123456",
    "type":"google"
    "google_setting": {
        "enable_two_step":0,
        "enable_gmail":0,
        "enable_ps":0
    }
    "facebook_setting": {
        "create_from":"",
        "is_z":false,
        "use":"MD5"
    }
}
错爱 2022-09-19 22:12:27

第二个问题可以考虑这个方法:
setting单独指定成一个struct,然后这个struct实现UnmarshalJSON方法,这个里面统一处理setting里的内容,可以直接保存起来,也可以让他不参与反序列化,只反序列化其他字段,setting直接以字节形式往后面流程走。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文