Блог AST-SoftPro
REST API дизайн: правила проектирования
Введение в проектирование REST API
REST (Representational State Transfer) — архитектурный стиль для построения веб-сервисов, основанный на HTTP. Он не является стандартом, но широко принят благодаря простоте и предсказуемости. При проектировании эффективного REST API важно придерживаться лучших практик: правильного использования HTTP-методов, структурирования маршрутов, обработки ошибок и обеспечения масштабируемости.
Ключевые принципы проектирования:
-
Использование стандартных HTTP-статусов для указания состояния запроса.
-
Чёткая структура URI (Uniform Resource Identifier).
-
Поддержка версионирования API.
-
Логичная организация путей без избыточности.
Версионирование API: зачем и как делать правильно
Версионирование необходимо, когда клиентские приложения зависят от определённой версии интерфейса. Без него обновления могут нарушить работу существующих клиентов.
Проблемы отсутствия версионирования
-
При изменении логики API все клиенты теряют совместимость.
-
Нет способа указать «это новая версия» без изменения URL.
-
Ошибки обработки данных из-за различий в формате ответов.
Методы версионирования
| Метод | Пример | Плюсы | Минусы |
|---|---|---|---|
| В пути (URI) | /api/v1/users | Простота, поддержка кэша браузера | Увеличивает длину URL при многих версиях |
| В заголовке Accept | application/vnd.company.api+json; version=2 | Не влияет на URI, гибко | Требует поддержки клиентом и сервером |
| Поддомены | https://v1.api.example.com/users | Чёткая изоляция версий | Сложнее управлять DNS и безопасностью |
Рекомендация: Использовать версионирование в пути (/api/v1/resource) — это наиболее распространённый и понятный способ. Избегать частого изменения API без предварительной документации.
Пагинация: как не перегружать клиент данных
Большинство ресурсов нельзя получить целиком за один запрос. Например, список пользователей может содержать миллионы записей. Поэтому применяется пагинация — разбиение на страницы по фиксированному числу элементов (лимит).
Проблемы при неправильной реализации
-
Клиент получает слишком много или мало данных.
-
Нет возможности указать, какие именно данные нужны дальше.
Стандартные параметры пагинации
| Параметр | Значение по умолчанию | Пример использования |
|---|---|---|
| page | 1 (первая страница) | /users?page=3 — третья страница |
| limit или per_page | 20–50 элементов | /users?limit=10 — по 10 на страницу |
| offset | 0 (сдвиг от начала списка) | /users?offset=40&limit=10 — с 41-го элемента |
Важно: Не использовать только offset. Лучше комбинировать page и limit, так как это проще для клиента. Избегать больших значений limit (например, >100) без явного согласия.
Поддержка сортировки и фильтрации на стороне пагинации
Часто клиент хочет не просто получить страницу, а отсортировать или отфильтровать данные внутри неё:
GET /users?sort=created_at&order=desc&limit=20&page=1
-
sort — поле для сортировки (обязательно).
-
order — направление (asc, desc). Допустимо только одно значение за запрос.
-
Фильтры по полю: /users?status=active.
Обработка ошибок: ясные и полезные ответы
Ошибки в REST API должны быть понятными для клиента, но не раскрывать внутренние детали системы (например, имена таблиц БД или конкретные ошибки аутентификации).
Типичные HTTP-статусы и их назначение
| Статус | Когда использовать | Пример сообщения |
|---|---|---|
| 400 Bad Request | Ошибка в формате запроса | «Неверный формат поля "email"» |
| 401 Unauthorized | Отсутствие аутентификации или неверные учетные данные | «Укажите корректный токен доступа» |
| 403 Forbidden | Доступ запрещён, даже при авторизации | «У вас нет прав на просмотр этого ресурса» |
| 404 Not Found | Ресурс не существует по указанному пути | «Ресурс с ID=12345 не найден» |
| 409 Conflict | Конфликт состояния (например, дублирование) | «Пользователь уже существует под этим email» |
| 429 Too Many Requests | Превышен лимит запросов за единицу времени | «Слишком много запросов. Попробуйте через 1 минуту» |
Рекомендации по формату ответа:
-
Поле error: краткое описание ошибки (не техническая деталь).
-
Поле code: числовой или строковый код ошибки.
-
Поле details (опционально): расширенная информация для разработчиков (логируется, но не показывается клиенту).
Пример ответа на ошибку:
{
"error": "User not found",
"code": 1002,
"details": "Record with id=54321 does not exist in the database."
}
- details — для внутреннего использования, не показывается в клиентском интерфейсе.
Фильтрация и поисковая логика: гибкость без избыточности
Клиенты часто хотят получать только нужные им данные. Это достигается через фильтры (по полю) и поиск (по тексту).
Различие между фильтром и поиском
-
Фильтр — точное совпадение или сравнение (eq, gt, lt).
-
Поиск — частичное совпадение, часто с подстановкой (%).
Примеры параметров:
GET /users?filter[status]=active&search=ivan&sort=name
-
filter используется для точных условий (например, статус заказа).
-
search — для текстового поиска по нескольким полям.
Поддержка нескольких полей в фильтре и поиске
GET /orders?filter[status]=completed&filter[payment_method]=card
-
Можно использовать несколько параметров filter[].
-
Не рекомендуется комбинировать search с множеством условий — это усложняет логику.
Безопасность и производительность: что ещё учитывать
Построение REST API требует не только корректности, но и устойчивости к нагрузке и угрозам:
-
Валидация входных данных на всех уровнях (не только в бизнес-логике).
-
Ограничение частоты запросов (rate limiting) — защита от DDoS.
-
Минимизация передачи данных — возвращать только нужные поля, не «всё подряд».
Пример: ответ с выборочными полями
Вместо:
{ "id": 123, "name": "Alice", "email": "a@b.com", "phone": "+7900..." }
-
Лучше возвращать только те поля, которые нужны клиенту.
-
Использовать fields или include для контроля структуры ответа:
GET /users?fields=name,email
Заключение: ключевые правила проектирования REST API
Для создания надёжного и удобного REST API следует придерживаться следующих правил:
-
Версионируйте API — используйте /api/vX/resource, избегайте частых изменений.
-
Используйте стандартные HTTP-методы: GET (чтение), POST (создание), PUT/PATCH (обновление/частичное обновление), DELETE (удаление).
-
Реализуйте пагинацию с параметрами page, limit. Избегайте больших лимитов.
-
Обрабатывайте ошибки чётко: используйте правильные HTTP-статусы, давайте понятные сообщения клиенту и технические — разработчику.
-
Поддерживайте фильтрацию и поиск, но не перегружайте клиент сложными условиями.
-
Не возвращайте лишние данные — делайте ответы компактными и настраиваемыми (через поля).
-
Добавьте rate limiting для защиты от злоупотреблений.
Следуя этим принципам, можно создать API, которое будет простым в интеграции, стабильным при масштабировании и понятным для всех сторон — клиентов, разработчиков и системных администраторов.