Логотип Workflow

Article

Updated at:

Rest Architecture

Stage 2. REST Essentials

REST — это практичный подход к проектированию HTTP API, который помогает сохранить понятную структуру по мере роста проекта. Базовая идея простая: API строится вокруг ресурсов, а поведение операций задаётся стандартной семантикой HTTP.

Ресурсом считается объект предметной области: books, users, orders, tasks. В REST путь URL идентифицирует ресурс, а HTTP-метод определяет, что нужно сделать с этим ресурсом.

REST basics diagram

Базовая модель REST

Надёжная последовательность проектирования:

  1. Определить имена ресурсов как существительные.
  2. Определить пути для коллекции и одного элемента.
  3. Сопоставить операции с HTTP-методами.
  4. Зафиксировать статус-коды и формат ответов.

Базовая карта ресурсов:

GET    /books
POST   /books
GET    /books/{id}
PUT    /books/{id}
DELETE /books/{id}

Этот шаблон легко повторять в разных модулях, поэтому контракт API остаётся предсказуемым.

Принципы, которые реально важны

Ресурсная модель означает, что путь показывает объект, с которым вы работаете, а не команду. Маршрут /books ресурсный, а /createBook командный.

Stateless-коммуникация означает, что каждый запрос содержит достаточно контекста для независимой обработки. Сервер не должен зависеть от скрытого состояния UI между вызовами.

Единообразный интерфейс означает, что похожие ситуации дают похожее поведение. Если два endpoint возвращают ошибку валидации, у них должен быть сопоставимый класс status code и единая форма error payload.

Семантика методов должна оставаться чистой: GET читает, POST создаёт, PUT заменяет, DELETE удаляет.

Именование и структура URL

Используйте существительные в путях и избегайте глаголов в названиях маршрутов. Не дублируйте действие в URL, если оно уже задано методом.

Избегайте:

  • /createBook
  • /updateBook/12
  • /deleteBook/12

Предпочитайте:

  • POST /books
  • PUT /books/12
  • DELETE /books/12

Путь коллекции обычно во множественном числе (/books), путь одного ресурса содержит идентификатор (/books/{id}), а вложенность должна быть умеренной и обоснованной.

Path-параметры и query-параметры

Path-параметр используйте тогда, когда значение однозначно указывает на один ресурс. Query-параметры используйте для фильтрации, сортировки, поиска и пагинации коллекции.

  • GET /books/12 — книга с id 12.
  • GET /books?author=rowling — список книг с фильтром по автору.
  • GET /books?sort=title&page=2&size=20 — список с сортировкой и пагинацией.

Если параметр обязателен для поиска конкретного объекта, это path. Если параметр меняет представление списка, это query.

Дисциплина status codes

Status codes — это не декоративная часть ответа, а протокольный сигнал для клиента, логов и мониторинга.

СитуацияРекомендуемый statusПочему
Список успешно получен200 OKУспешное чтение данных
Ресурс создан201 CreatedНа сервере создан новый объект
Ресурс обновлён с возвратом тела200 OKОбновление успешно, данные возвращены
Ресурс удалён204 No ContentУдаление успешно, тело не требуется
Некорректный ввод400 Bad RequestОшибка формата или валидации запроса
Ресурс не найден404 Not FoundЦелевой объект отсутствует
Конфликт состояния409 ConflictЗапрос конфликтует с текущим состоянием ресурса

Если возвращать 200 во всех случаях, клиент теряет протокольный смысл и усложняется интеграция.

Единый формат ответов и ошибок

Для коллекций формат-обёртка обычно лучше, чем “голый массив”. Так проще добавлять метаданные без ломающих изменений.

Пример ответа списка:

{
  "items": [
    { "id": 12, "title": "Clean Code" },
    { "id": 13, "title": "Refactoring" }
  ],
  "meta": {
    "page": 1,
    "size": 20,
    "total": 125
  }
}

Пример ответа с ошибкой:

{
  "error": "validation_failed",
  "message": "title is required",
  "details": [
    { "field": "title", "reason": "must not be blank" }
  ],
  "traceId": "a4f8d2e1"
}

Стабильная структура ошибок упрощает обработку на frontend и ускоряет диагностику инцидентов.

Практический сценарий: онлайн-библиотека

Предположим, API управляет книгами.

Пользователь открывает каталог. Клиент отправляет GET /books?page=1&size=20. Сервер возвращает список с полями items и meta.

Пользователь добавляет книгу. Клиент отправляет POST /books с названием и автором. Сервер создаёт запись и возвращает 201 Created вместе с созданным объектом.

Пользователь редактирует книгу 12. Клиент отправляет PUT /books/12 с обновлённым состоянием. Сервер валидирует поля, обновляет запись и возвращает 200 OK.

Пользователь пытается открыть удалённую книгу 99. Клиент отправляет GET /books/99. Сервер возвращает 404 Not Found в стандартном error формате.

Пользователь удаляет книгу 12. Клиент отправляет DELETE /books/12. Сервер удаляет запись и возвращает 204 No Content.

Этот сценарий покрывает базу REST: ресурсные пути, методы, status codes, метаданные списка и единый формат ошибок.

Базовый подход к versioning

Версию API лучше фиксировать явно с самого начала. Частый вариант: префикс в пути, например /api/v1/books.

Польза в том, что при будущих несовместимых изменениях можно добавить /api/v2, не ломая сразу всех существующих клиентов.

Чеклист REST best practices

  • Используйте ресурсные пути на существительных.
  • Держите единый стиль именования (lowercase, множественное число для коллекций).
  • Не используйте глаголы в URL.
  • Применяйте методы по семантике HTTP.
  • Возвращайте осмысленные status codes под сценарий.
  • Держите единый формат успешных и error-ответов.
  • Используйте query-параметры для фильтрации, сортировки и пагинации.
  • Контролируйте глубину вложенности URL.
  • Добавьте версионирование API до публичного масштабирования.

Частые ошибки

Распространённая ошибка — строить API как RPC и создавать команды вида /run, /execute, /process для большинства операций. Такая схема скрывает ресурсную модель и усложняет интеграцию.

Другая ошибка — непоследовательная обработка ошибок, когда один endpoint возвращает структурированную валидацию, а другой обычный текст. В итоге клиентский код дробится на множество частных случаев.

Ещё одна ошибка — избыточно глубокие пути для каждой связи между сущностями. Это ухудшает читаемость и усиливает связь клиента с внутренней структурой backend.

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

Авторизуйтесь чтоб пройти тесты

Quiz

Проверьте, что вы усвоили

Practice

Интерактивная практика

Выполните задания и сразу проверьте ответ.