Стоит ли использовать глаголы в URL?
В REST за действие отвечает HTTP метод, а не строка пути.
Junior Level
Для чистого REST глаголы в URL не рекомендуются — действие выражается HTTP методом. Однако на практике многие API (Stripe, GitHub) используют глаголы для сложных операций, не укладывающихся в CRUD.
В REST за действие отвечает HTTP метод, а не строка пути.
Почему глаголы — это плохо?
- ❌
GET /deleteUser/1— глагол в URL, метод GET для удаления (очень плохо!) - ❌
POST /saveOrder— глагол, это уже RPC, а не REST - ✅
DELETE /users/1— правильно: метод DELETE, ресурс users - ✅
POST /orders— правильно: метод POST, ресурс orders
Правильный подход:
// Неправильно:
POST /deleteUser/1
POST /saveOrder
GET /findUsers?name=Ivan
// Правильно:
DELETE /users/1
POST /orders
GET /users?name=Ivan
Простое правило:
- URI — это существительное (ресурс)
- HTTP Method — это глагол (действие)
Middle Level
Почему глаголы в URL — это проблема?
- Нарушение семантики кэширования: Прокси-серверы знают, что
GETбезопасен. Если естьGET /delete-all, прокси может “предзагрузить” этот URL - Сложность документации: Вместо стандартного набора действий — бесконечный список кастомных методов
- RPC вместо REST:
/deleteUser,/saveOrderпревращает REST в Remote Procedure Call
Паттерн “Ресурс как действие”
Если бизнес-логика требует сложного процесса, Senior-архитектор превращает действие в ресурс.
Пример: Отмена заказа
- Допустимо, но есть варианты лучше:
POST /orders/1/cancel— GitHub, Stripe используют этот подход. - Хорошо (PATCH):
PATCH /orders/1с телом{"status": "CANCELLED"} - Лучше (Resource-based):
POST /orders/1/cancellation— создаём “сущность отмены”. Это позволяет хранить метаданные: кто отменил, когда, по какой причине
Пример: Поиск
- Плохо:
GET /findUsers?name=Ivan - Хорошо:
GET /users?name=Ivan
Дизайн “State Machine” в REST
Если приложение — сложная машина состояний (жизненный цикл заявки), не плодите эндпоинты /approve, /reject, /review. Используйте HATEOAS: сервер возвращает текущее состояние и список допустимых ссылок на переходы.
Производительность
- Использование глаголов часто скрывает неэффективные “тяжёлые” операции
- Ресурсный подход заставляет думать о том, как данные хранятся и индексируются
- Глагольные эндпоинты в
POSTчасто забывают делать идемпотентными.- Идемпотентность — свойство: повторный вызов даёт тот же результат.
- POST по умолчанию не идемпотентен (два POST = два ресурса).
- Если
POST /orders/1/cancelвызван дважды — заказ отменится дважды с побочными эффектами.
Senior Level
Превращение действий в ресурсы
Пример: Калькулятор
Для математических расчётов или миграций данных, где нет явного ресурса, допустимо использовать существительное-контроллер:
POST /calculators/tax-estimator
Это всё ещё не глагол, но отступление от чистого CRUD.
HATEOAS и State Machine
HATEOAS реализует паттерн State Machine на уровне сетевого протокола:
- Сервер возвращает текущее состояние ресурса
- Вместе с ним — список допустимых ссылок на переходы
- Клиент следует по ссылке, не зная, “глагол” это или нет
- Это радикально снижает связность между фронтендом и бэкендом
Диагностика
- Log Analysis: По эндпоинтам с глаголами сложнее строить воронки аналитики. Ресурсный подход позволяет группировать запросы по сущностям
- Security: Глаголы в URL становятся мишенью для сканеров уязвимостей, так как выдают логику работы приложения (Command Injection риски)
Edge Cases
- Legacy системы: При интеграции со старыми SOAP/XML системами часто приходится использовать “туннелирование” методов, но даже там старайтесь оборачивать их в ресурсные обёртки на уровне API Gateway
- Контроллер-эндпоинты: Допустимо использовать существительное-контроллер для сложных операций без явного ресурса
🎯 Шпаргалка для интервью
Обязательно знать:
- Для чистого REST глаголы в URL не рекомендуются — действие выражается HTTP методом
- URI = существительное (ресурс), HTTP Method = глагол (действие)
- GET /deleteUser — критическая ошибка: прокси может предзагрузить и случайно удалить
- Паттерн «ресурс как действие»: POST /orders/1/cancellation вместо POST /orders/1/cancel
- HATEOAS реализует State Machine: сервер возвращает текущее состояние + допустимые переходы
- Глаголы в URL выдают логику приложения и становятся мишенью для сканеров уязвимостей
- Для математических расчётов допустимо существительное-контроллер: POST /calculators/tax-estimator
Частые уточняющие вопросы:
- Как правильно отменить заказ? — PATCH /orders/1 с
{"status": "CANCELLED"}или POST /orders/1/cancellation - Почему GET /deleteAll — это плохо? — Браузеры и прокси могут предзагружать GET, что вызовет удаление
- Когда глаголы допустимы? — Legacy-интеграции, RPC-эндпоинты, но лучше оборачивать в ресурсные обёртки
- Как HATEOAS заменяет глаголы? — Сервер возвращает ссылки на допустимые действия для текущего состояния
Красные флаги (НЕ говорить):
- «Глаголы в URL — это нормально для REST API» — нарушают семантику REST и кэширование
- «POST /saveUser — это REST» — это RPC, а не REST
- «GET /logout — хороший подход» — GET обязан быть безопасным, браузеры могут предзагружать
- «Глаголы упрощают документацию» — наоборот, ломают стандартный набор действий и усложняют OpenAPI
Связанные темы:
- [[Как правильно именовать REST endpoints]]
- [[Что такое RESTful API дизайн]]
- [[Что такое HATEOAS]]
- [[Какие основные HTTP методы используются в REST]]
- [[Является ли POST идемпотентным]]