Валидация данных в Go (Golang): библиотеки и практические примеры
Валидация данных — один из ключевых аспектов разработки надёжных веб-приложений и API на Go. Без корректной проверки входящих данных приложение становится уязвимым к ошибкам, некорректному вводу и атакам. В этой статье мы рассмотрим три популярные библиотеки для валидации в Go: go-playground/validator, ozzo-validation и govalidator, а также разберём примеры их использования.
Зачем нужна валидация в Go?
Go — строго типизированный язык, но это не спасает от логических ошибок в данных: пустые строки, некорректные email, числа вне допустимого диапазона. Валидация позволяет:
- Гарантировать целостность данных на входе;
- Упростить обработку ошибок;
- Повысить безопасность приложения;
- Сократить количество boilerplate-кода.
1. go-playground/validator — золотой стандарт
Самая популярная библиотека (более 15k звёзд на GitHub). Позволяет описывать правила валидации прямо в тегах структур.
Установка
go get github.com/go-playground/validator/v10
Базовый пример
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
type User struct {
Name string `validate:"required,min=3,max=50"`
Email string `validate:"required,email"`
Age int `validate:"gte=18,lte=120"`
}
func main() {
validate := validator.New()
user := User{
Name: "A",
Email: "invalid-email",
Age: 15,
}
err := validate.Struct(user)
if err != nil {
for _, err := range err.(validator.ValidationErrors) {
fmt.Printf("Поле: %s, Ошибка: %s\n", err.Field(), err.Tag())
}
}
}
Кастомные валидаторы
validate.RegisterValidation("is-valid-username", func(fl validator.FieldLevel) bool {
return len(fl.Field().String()) >= 5
})
type Login struct {
Username string `validate:"required,is-valid-username"`
}
2. ozzo-validation — гибкость и читаемость
Библиотека ozzo-validation предлагает fluent-интерфейс для построения правил. Хорошо подходит для сложных бизнес-правил.
Установка
go get github.com/go-ozzo/ozzo-validation/v4
Пример использования
package main
import (
"fmt"
validation "github.com/go-ozzo/ozzo-validation/v4"
"github.com/go-ozzo/ozzo-validation/v4/is"
)
type Order struct {
ProductID string
Quantity int
Email string
}
func (o Order) Validate() error {
return validation.ValidateStruct(&o,
validation.Field(&o.ProductID, validation.Required, validation.Length(5, 20)),
validation.Field(&o.Quantity, validation.Required, validation.Min(1), validation.Max(100)),
validation.Field(&o.Email, validation.Required, is.Email),
)
}
func main() {
order := Order{ProductID: "AB", Quantity: 0, Email: "bad"}
err := order.Validate()
if err != nil {
fmt.Println(err)
}
}
Особенности
- Отсутствие тегов — правила пишутся в коде;
- Лёгкая интеграция с пользовательскими типами;
- Поддержка условной валидации.
3. govalidator — простота для небольших проектов
Легковесная библиотека с набором готовых функций для проверки строк, чисел и структур.
Установка
go get github.com/asaskevich/govalidator
Пример
package main
import (
"fmt"
"github.com/asaskevich/govalidator"
)
func main() {
// Проверка строк
fmt.Println(govalidator.IsEmail("test@example.com")) // true
fmt.Println(govalidator.IsURL("https://pythonlib.ru")) // true
fmt.Println(govalidator.IsInt("123")) // true
// Валидация структуры
type User struct {
Name string `valid:"required,alpha"`
Email string `valid:"required,email"`
}
u := User{Name: "John123", Email: "test"}
ok, err := govalidator.ValidateStruct(u)
if !ok {
fmt.Println(err)
}
}
Сравнение библиотек
Выбор инструмента зависит от задач:
- go-playground/validator — для больших проектов, где важна скорость и стандартизация;