确定POST数据值是否与结构字段类型匹配

huangapple go评论86阅读模式
英文:

Determine if POST data value matches struct field type

问题

使用gin框架,我正在尝试确定POST的数据是否与结构字段类型不匹配,并通知API用户其错误。

type CreateApp struct {
    LearnMoreImage string `db:"learn_more_image" json:"learn_more_image,omitempty" valid:"string,omitempty"`
    ApiVersion     int64  `db:"api_version" json:"api_version" valid:"int,omitempty"`
}
...
func CreateApps(c *gin.Context) {
    var json models.CreateApp
    c.Bind(&json)
}

所以当我进行POST请求时:

curl -H "Content-Type: application/json" -d '{"learn_more_image":"someimage.jpg","api_version":"somestring"}' "http://127.0.0.1:8080/v1.0/apps"

我想确定字段api_version的POST数据(作为字符串传递)是否与其绑定到的结构字段(整数)不匹配。如果数据不匹配,我想向用户发送一条消息。出于这个原因,我希望能够循环遍历gin上下文的数据并进行检查。

gin函数c.Bind()似乎会忽略无效数据以及所有随后的数据字段。

英文:

Using the gin framework I am trying to determine if POST'ed data does not match the struct field type and inform API user of their error.

type CreateApp struct {
    LearnMoreImage string `db:"learn_more_image" json:"learn_more_image,omitempty" valid:"string,omitempty"`
    ApiVersion     int64  `db:"api_version" json:"api_version" valid:"int,omitempty"`
}
...
func CreateApps(c *gin.Context) {
    var json models.CreateApp
    c.Bind(&json)

So when I POST

curl -H "Content-Type: application/json" -d '{"learn_more_image":"someimage.jpg","api_version":"somestring"}' "http://127.0.0.1:8080/v1.0/apps"

I would like to determine whether the POST'ed data for field 'api_version' (passed as string) does not match the struct field it is being binded to (int). If the data doesnt match I'd like to send a message back to the user. Its for this reason I was hoping I could loop through the gin contexts data and check it.

The gin function 'c.Bind()' seems to omit invalid data and all subsequent data fields with it.

答案1

得分: 1

Gin内置了一个验证引擎:https://github.com/bluesuncorp/validator/blob/v5/baked_in.go

但你也可以使用自己的验证引擎或完全禁用它。

验证器不会验证原始数据(JSON字符串),而是验证绑定的结构体:

LearnMoreImage string `db:"learn_more_image" json:"learn_more_image,omitempty" binding:"required"`
ApiVersion     int64  `db:"api_version" json:"api_version" binding:"required,min=1"`

注意这里的 binding:"required,min=1"

然后:

err := c.Bind(&json)

或者使用一个中间件并读取 c.Errors

更新:

有三种解决方法:

  • 自己验证JSON字符串(不能使用encoding/json完成)
  • 验证整数是否大于0 binding:"min=1"
  • 使用 map[string]interface{} 而不是结构体,然后验证类型。
func endpoint(c *gin.Context) {
    var json map[string]interface{}
    c.Bind(&json)
    struct, ok := validateCreateApp(json)
    if ok { /** DO SOMETHING */ }
}

func validateCreateApp(json map[string]interface{}) (CreateApp, bool) {
    learn_more_image, ok := json["learn_more_image"].(string)
    if !ok {
        return CreateApp{}, false
    }
    api_version, ok = json["api_version"].(int)
    if !ok {
        return CreateApp{}, false
    }
    return CreateApp{
        learn_more_image, api_version,
    }
}
英文:

Gin has a built-in validation engine: https://github.com/bluesuncorp/validator/blob/v5/baked_in.go

but you can use your own or disable it completely.

The validator does not validate the wire data (json string), instead it validates the binded struct:

LearnMoreImage string `db:"learn_more_image" json:"learn_more_image,omitempty" binding:"required"`
ApiVersion     int64  `db:"api_version" json:"api_version" binding:"required,min=1"`

Notice this: binding:"required,min=1"

Then:

err := c.Bind(&json)

or use a middleware and read c.Errors.

UPDATED:

Three workarounds:

  • Validate the json string your own (it can not be done with enconding/json)

  • Validate if integer is > 0 binding:"min=1"

  • Use a map[string]interface{} instead of a Struct, then validate the type.

     func endpoint(c *gin.Context) {
         var json map[string]interface{}
         c.Bind(&json)
         struct, ok := validateCreateApp(json)
         if ok { /** DO SOMETHING */ }
     }
    
     func validateCreateApp(json map[string]interface{}) (CreateApp, bool) {
     	learn_more_image, ok := json["learn_more_image"].(string)
     	if !ok {
     		return CreateApp{}, false
     	}
     	api_version, ok = json["api_version"].(int)
     	if !ok {
     		return CreateApp{}, false
     	}
     	return CreateApp{
     		learn_more_image, api_version,
     	}
     }
    

huangapple
  • 本文由 发表于 2015年6月7日 17:19:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/30691905.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定