Валидация данных в Go: обзор библиотек и подходов

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Валидация данных в 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)
    }
}

Сравнение библиотек

Выбор инструмента зависит от задач:

Рекомендаций