#validation #go #go-gin
# #валидация #Вперед #гоу-джин
Вопрос:
Я попытался протестировать проверку данных запроса в фреймворке go-gin, пока не добрался до этого кода, который работает нормально.
// RegisterEmailPasswordValidator it is used for validation and json marshalling
type RegisterEmailPasswordValidator struct {
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,gte=6,lte=30"`
}
// Validate used in views
func (v *RegisterEmailPasswordValidator) Validate( c *gin.Context) error {
if err := c.ShouldBindJSON(v); err != nil {
return err
}
return nil
}
// use it like this in my controller
var validator validations.RegisterEmailPasswordValidator
err := validator.Validate(c)
Чтобы быть СУХИМ, я попытался добавить глобальную функцию для проверки ответственности за все структуры. Я попытался добавить функцию с пустым интерфейсом, как показано ниже.
// Validate used in views
func Validate(c *gin.Context, customValidator interface{}) error {
if err := c.ShouldBindJSON(amp;customValidator); err != nil {
return err
}
return nil
}
// use it like this in my controller
var validator validations.RegisterEmailPasswordValidator
err := validations.Validate(c, amp;validator)
Но это не работает, когда я отправляю CustomValidator в ShouldBindJSON, он использует пустой интерфейс, а не динамический тип.
Есть ли какой-нибудь способ использовать динамический тип CustomValidator без указания его типа? Я попытался отразить.
Есть ли лучший способ быть СУХИМ в этой ситуации в go?
Комментарии:
1. @ILoveReflection Я попробовал ваше предложение, есть ошибка json: Unmarshal(проверки без указателей. RegisterEmailPassword)
2. Я неправильно понял код. Я не вижу, где используется функция проверки. Игнорируйте мой предыдущий комментарий.
3. Вы не должны отправлять указатель на интерфейс своей функции. Также я предполагаю, что ввод в ShouldBindJson — это интерфейс, и он у вас уже есть, зачем передавать указатель на этот интерфейс?
4. @Mastisa Принятый ответ — это именно то, что я предложил. Тем не менее, код в вопросе не использует функцию проверки, поэтому я все еще в замешательстве.
5. Я точно не помню ваше предложение, но в вашем предложении была ошибка, о которой я упоминал.
Ответ №1:
Вы должны передавать интерфейс как есть, а не указатель на интерфейс. что-то вроде этого :
// Validate used in views
func Validate(c *gin.Context, customValidator interface{}) error {
if err := c.ShouldBindJSON(customValidator); err != nil {
return err
}
return nil
}
// use it like this in my controller
var validator validations.RegisterEmailPasswordValidator
err := validations.Validate(c, amp;validator)
Причина в том, что указатели в Go — это не то же самое, что указатели в C / C , они сохраняют ссылку на тип и значение. Указатель на интерфейс не является указателем на тип, который он содержит, но это указатель на сам интерфейс, тип — это интерфейс. В ShouldBindJSON
функции пытается получить объект путем отражения, но он получает тип интерфейса и ссылку, а не validator
ссылку s, поэтому он не может выполнить свою работу, поскольку ему нужен тип, а не интерфейс.
Комментарии:
1. Указатели в Go такие же, как и указатели в C / C . Это разные значения интерфейса.