Валидация данных в Go (Golang): библиотеки, подходы и примеры кода

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

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

Начать курс

Валидация данных в Go (Golang): полное руководство по библиотекам и подходам

Валидация данных — критически важная часть любого веб-приложения, API или микросервиса. В Go (Golang) эта задача решается как стандартными средствами, так и мощными сторонними библиотеками. В этой статье мы разберём основные подходы, популярные библиотеки и приведём практические примеры кода.

Зачем нужна валидация в Go?

Go — строго типизированный язык, что уже даёт некоторую защиту от некорректных данных. Однако типы не проверяют бизнес-правила: email должен содержать «@», возраст — быть в диапазоне 0–120, пароль — иметь минимальную длину. Без валидации вы рискуете получить:

  • SQL-инъекции и XSS-атаки
  • Некорректные данные в БД
  • Неожиданные паники и ошибки времени выполнения

Встроенные средства валидации

Простейшая валидация делается «руками» в функциях. Пример:

type User struct {
    Name  string
    Email string
    Age   int
}

func ValidateUser(u User) error {
    if u.Name == "" {
        return errors.New("name is required")
    }
    if !strings.Contains(u.Email, "@") {
        return errors.New("invalid email")
    }
    if u.Age < 0 || u.Age > 150 {
        return errors.New("age must be between 0 and 150")
    }
    return nil
}

Этот подход прост, но для сложных структур становится громоздким и трудно поддерживаемым. Поэтому Go-сообщество создало специализированные библиотеки.

1. go-playground/validator — стандарт де-факто

Ссылка: github.com/go-playground/validator/v10

Это самая популярная библиотека валидации в Go (более 15k звёзд на GitHub). Она использует теги структур (struct tags) для декларативного описания правил.

Установка

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=2,max=50"`
    Email    string `validate:"required,email"`
    Age      int    `validate:"gte=0,lte=150"`
    Password string `validate:"required,min=8"`
}

func main() {
    validate := validator.New()

    user := User{
        Name:     "A",
        Email:    "not-email",
        Age:      200,
        Password: "123",
    }

    err := validate.Struct(user)
    if err != nil {
        for _, e := range err.(validator.ValidationErrors) {
            fmt.Printf("Поле: %s, правило: %s, значение: %v\n", e.Field(), e.Tag(), e.Value())
        }
    }
}

Вывод:

Поле: Name, правило: min, значение: A
Поле: Email, правило: email, значение: not-email
Поле: Age, правило: lte, значение: 200
Поле: Password, правило: min, значение: 123

Популярные теги-правила

  • required — поле обязательно
  • min, max — для чисел и строк
  • len — точная длина
  • email — проверка email
  • url — проверка URL
  • gte, lte — больше/меньше или равно
  • oneof — одно из значений (oneof=admin user)

Кастомные валидаторы

validate.RegisterValidation("is-odd", func(fl validator.FieldLevel) bool {
    return fl.Field().Int()%2 != 0
})

type MyStruct struct {
    Number int `validate:"is-odd"`
}

2. ozzo-validation — альтернатива с цепочками

Ссылка: github.com/go-ozzo/ozzo-validation/v4

Эта библиотека предлагает более «Go-идиоматичный» подход: правила задаются через функции, а не теги. Это даёт большую гибкость и читаемость.

Пример

package main

import (
    "fmt"
    validation "github.com/go-ozzo/ozzo-validation/v4"
    "github.com/go-ozzo/ozzo-validation/v4/is"
)

type User struct {
    Name     string
    Email    string
    Age      int
    Password string
}

func (u User) Validate() error {
    return validation.ValidateStruct(&u,
        validation.Field(&u.Name, validation.Required, validation.Length(2, 50)),
        validation.Field(&u.Email, validation.Required, is.Email),                    

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