> Почему важно валидировать входные данные (Go)

Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы

Компании: Т-Банк

Стек: Go

> Пример ответа

Короткий ответ

Валидация входных данных - это первая линия защиты от некорректных, вредоносных или неожиданных данных. Она предотвращает ошибки бизнес-логики, SQL-инъекции, path traversal, переполнения буфера и некорректные состояния системы. В Go, где многое строится на явной обработке ошибок, валидация также обеспечивает контракт между слоями приложения и внешним миром. Без неё система становится хрупкой, непредсказуемой и уязвимой.

Подробное объяснение

Валидация входных данных решает несколько задач:

  • Безопасность: некорректные данные могут эксплуатировать уязвимости - например, инъекции, XSS, SSRF. Валидация ограничивает поверхность атаки.
  • Целостность данных: данные, попадающие в БД или кэш, должны соответствовать схеме и бизнес-правилам. Иначе - деградация данных и сложные баги.
  • Предсказуемость: валидация на границе системы позволяет не тащить ошибки вглубь, где их сложнее диагностировать.
  • UX и API-контракт: понятные ошибки валидации помогают клиентам быстро исправить запрос.
  • Производительность: ранняя отбраковка невалидных данных экономит ресурсы на обработку и хранение.

В Go валидация часто реализуется через структурные теги (validate:"required,email"), кастомные функции или middleware. Важно разделять: синтаксическая валидация (формат, типы, диапазоны) и семантическая (бизнес-правила, права доступа). Первая - на уровне DTO, вторая - в сервисном слое.

На практике

Для backend на Go валидация обычно происходит на нескольких уровнях:

  1. Transport layer: проверка заголовков, query-параметров, JSON-структуры.
  2. DTO layer: структурная валидация через теги или ручные проверки.
  3. Service layer: бизнес-правила, проверка существования связанных сущностей, прав доступа.

Хорошая практика - использовать библиотеки вроде go-playground/validator для декларативной валидации, но не злоупотреблять: сложные правила лучше выносить в код. Также важно возвращать структурированные ошибки (например, {"field": "email", "error": "invalid format"}), а не просто 400 Bad Request.

Пример кода

GO
type CreateUserRequest struct {
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required,min=8,max=72"`
Age int `json:"age" validate:"gte=0,lte=130"`
}
func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request) {
var req CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid JSON", http.StatusBadRequest)
return
}
validate := validator.New()
if err := validate.Struct(&req); err != nil {
// собираем структурированный ответ
var out []map[string]string
for _, e := range err.(validator.ValidationErrors) {
out = append(out, map[string]string{
"field": e.Field(),
"error": e.Tag(),
})
}
writeJSON(w, http.StatusBadRequest, map[string]any{"errors": out})
return
}
// дальше - сервисный слой с бизнес-валидацией
if err := h.svc.CreateUser(r.Context(), req); err != nil {
// обработка ошибок сервиса
}
}

Как отвечать на собеседовании

Начни с безопасности и целостности данных - это ключевые причины. Затем переходи к уровням валидации и разделению синтаксиса и семантики. Упомяни, что в Go валидация - это часть контракта API, и приведи пример структурированных ошибок. Если спросят про производительность - скажи, что ранняя отбраковка дешевле, чем обработка мусорных данных. Не углубляйся в конкретные библиотеки, если не спрашивают.

Что проверяет интервьюер

  • Понимание разницы между синтаксической и семантической валидацией.
  • Умение объяснить, где именно валидировать (слой, граница системы).
  • Знание типичных уязвимостей, связанных с отсутствием валидации.
  • Практический опыт: как возвращать ошибки, как структурировать DTO.
  • Понимание trade-off: избыточная валидация vs гибкость API.

Типичные ошибки

  • Валидация только на клиенте - сервер должен доверять только себе.
  • Смешивание синтаксической и бизнес-валидации в одном месте.
  • Возврат неструктурированных ошибок (400 Bad Request без деталей).
  • Игнорирование валидации query-параметров и заголовков.
  • Дублирование правил валидации в разных слоях без единого источника правды.
  • Использование panic или log.Fatal при невалидных данных - вместо возврата ошибки.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью