Вопрос 13 · Раздел 6

Стоит ли использовать глаголы в URL?

В REST за действие отвечает HTTP метод, а не строка пути.

Версии по языкам: English Russian Ukrainian

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 — это проблема?

  1. Нарушение семантики кэширования: Прокси-серверы знают, что GET безопасен. Если есть GET /delete-all, прокси может “предзагрузить” этот URL
  2. Сложность документации: Вместо стандартного набора действий — бесконечный список кастомных методов
  3. 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 идемпотентным]]