Питання 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 ідемпотентним]]