Product / Full stack / Урок 04

Go backend и REST API

Строим компактный API с ясными границами и обработкой ошибок.

Видео · 1:05Материалы · 12 минутРусскийОбновлён 02 августа 2026
Для кого
Разработчики, которым нужен простой production API без лишнего framework-слоя.
Перед началом
Пользовательский сценарий и описание входных и выходных данных.
01:05 Озвучка · встроенный текст

Моё обучение

Прогресс и заметка

Войдите, чтобы сохранять прогресс, закладки и личные заметки.

Войти

Материалы / 12 минут

Построить компактный Go API с явной валидацией, единым форматом ошибок и ограниченными таймаутами.

01

Handler — это граница, а не бизнес-логика

HTTP-handler читает запрос, ограничивает его размер, валидирует форму и вызывает use case. Решения о доступе к данным и правила продукта не должны зависеть от ResponseWriter.

Такая граница позволяет тестировать поведение без запуска сервера и менять транспорт, не переписывая основную логику.

02

Ошибки являются частью API

Клиенту нужен стабильный код ошибки, безопасное сообщение и request ID. Внутренняя причина остаётся в структурированном логе.

Используйте HTTP-статусы последовательно: 400 для формы запроса, 401 для отсутствующей сессии, 403 для запрещённого действия, 404 для неизвестного ресурса и 409 для конфликта состояния.

  • Не возвращайте stack trace или текст SQL-ошибки.
  • Ограничивайте тело запроса до декодирования JSON.
  • Завершайте внешние операции через context deadline.
03

Сервер должен уметь останавливаться

Настройте ReadHeaderTimeout, IdleTimeout и graceful shutdown. При остановке новый трафик перестаёт приниматься, а активные запросы получают короткое окно на завершение.

Health endpoint проверяет жизнеспособность процесса, но не должен выполнять тяжёлые запросы к каждой зависимости.

Узкий HTTP-handler go
func createProject(w http.ResponseWriter, r *http.Request) {
    r.Body = http.MaxBytesReader(w, r.Body, 1<<20)
    var input CreateProjectInput
    if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
        writeError(w, http.StatusBadRequest, "invalid_request")
        return
    }
    result, err := projects.Create(r.Context(), input)
    writeResult(w, result, err)
}

Практика

Реализуйте один API-сценарий

Добавьте endpoint, который проходит через валидацию, use case, хранилище и единый ответ.

  1. 01

    Опишите входной DTO и допустимые значения.

  2. 02

    Добавьте ограничение размера тела и запрет неизвестных полей.

  3. 03

    Сопоставьте доменные ошибки с HTTP-статусами.

  4. 04

    Напишите httptest для успеха, неверного ввода и конфликта.

Критерии готовности

  • Handler не содержит SQL и продуктовых правил.
  • Ошибки имеют стабильный машинный код.
  • Размер тела и время выполнения ограничены.
  • Основные ветки endpoint покрыты httptest.