Определите, соответствует ли значение данных POST типу поля структуры

Используя структуру 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)

Итак, когда я отправляю сообщение

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

Я хотел бы определить, соответствуют ли данные POST для поля api_version (переданное как строка) полю структуры, к которому оно привязано (int). Если данные не совпадают, я хотел бы отправить сообщение пользователю. По этой причине я надеялся, что смогу просмотреть данные контекстов джина и проверить их.

Функция gin 'c.Bind ()', похоже, опускает недопустимые данные и все последующие поля данных с ними.


person Aaron Kenny    schedule 07.06.2015    source источник


Ответы (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 самостоятельно (это невозможно сделать с помощью enconding / json)
  • Проверить, если целое число> 0 привязка: "min = 1"
  • Используйте map [string] interface {} вместо Struct, затем проверьте тип.

    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,
        }
    }
    
person manucorporat    schedule 07.06.2015
comment
Спасибо. Я попытался использовать c.Errors, но он не подходит, поскольку возвращаемая ошибка json: невозможно демаршалировать строку в значение Go типа int64, не указывает поле, в котором произошла ошибка. Любые советы о том, как вручную проверить данные POST, хранящиеся в контексте gin? - person Aaron Kenny; 07.06.2015
comment
попробуйте подход map [string] interface {} ... отстой, что стандартная библиотека не возвращает лучшее сообщение об ошибке. - person manucorporat; 07.06.2015