Як правильно іменувати REST endpoints?
Іменування ендпоінтів — це створення зрозумілого і передбачуваного API.
Junior Level
Іменування ендпоінтів — це створення зрозумілого і передбачуваного API.
Основні правила:
- Використовуйте іменники, а не дієслова:
- ✅
GET /users/1 - ❌
GET /getUser/1
- ✅
- Використовуйте множину:
- ✅
/users,/orders,/products - ❌
/user,/order,/product
- ✅
- Використовуйте kebab-case:
- ✅
/audit-logs,/user-profiles - ❌
/audit_logs,/userProfiles
- ✅
- Використовуйте нижній регістр:
- ✅
/users/active - ❌
/Users/Active
- ✅
Приклади:
GET /users — отримати всіх користувачів
GET /users/1 — отримати користувача з ID 1
POST /users — створити користувача
GET /users/1/orders — отримати замовлення користувача
GET /users?role=admin — відфільтрувати користувачів за роллю
Фільтрація і пошук:
- ✅
/users?role=admin&status=active— параметри запиту - ❌
/users/role/admin— не робіть URI ієрархічним там, де ієрархії немає
Middle Level
Senior-правила іменування:
- Множина:
/usersпредставляє колекцію,/users/1— елемент колекції - Kebab-case: Дефіс — стандарт для URL (RFC 3986), краще сприймається пошуковиками
- Нижній регістр: URL чутливі до регістру на деяких серверах (Linux/Nginx)
Як бути з діями (Actions)?
Якщо дія не вкладається в CRUD (наприклад, “активувати користувача”):
- Resource-oriented (найкращий):
PATCH /users/1з тілом{"status": "ACTIVE"} - Sub-resource:
POST /users/1/activation— створюємо “сутність активації” - Controller-style (допустимо):
POST /users/1/activate— для складних команд
Пошук і фільтрація
- ✅
/users?role=admin— Query Params для фільтрації - ❌
/users/role/admin— URI не повинен бути ієрархічним без ієрархії
“Search-only” ендпоінти
У системах типу Elasticsearch використовують префікс _: POST /users/_search. Це допомагає уникнути колізій з ID ресурсів.
Прикордонні випадки
- Trailing Slash:
/users/і/users— два різних ресурси. НалаштуйтеStrictTrailingSlashPatternMatch. За замовчуванням Spring Boot 3+ робить 308 redirect з/users/на/users. Якщо це небажано, налаштуйтеuseTrailingSlashMatchу конфігурації. - ID у шляху vs у заголовку: Як правило, не передавайте ID поточного користувача в шляху, якщо він вже є в JWT. Використовуйте
/users/me/profile. Виняток — адміністративні ендпоінти, де адмін працює з чужим ID. Це запобігає IDOR (Insecure Direct Object Reference) атакам.- IDOR (Insecure Direct Object Reference) — атака, при якій зловмисник підміняє ID в URL (
/users/123→/users/124), отримуючи доступ до чужих даних. Захист: звіряти ID з URL з ID у JWT.
- IDOR (Insecure Direct Object Reference) — атака, при якій зловмисник підміняє ID в URL (
Діагностика
- 404 vs 405: Якщо ресурс існує, але метод не підходить — повернути 405 Method Not Allowed із заголовком
Allow, а не 404 - URI Length: Браузери і проксі обмежують довжину URL (2048 або 8192 символи). При занадто багатьох фільтрах — переходьте на
POST /_search
Senior Level
Складні сценарії іменування
Matrix Parameters
Рідко використовувана можливість URL;param=value (наприклад, /users;status=active/orders). Spring MVC підтримує через @MatrixVariable. Корисні для передачі параметрів у середину шляху.
IDOR Prevention
Як правило, не передавайте ID поточного користувача в шляху, якщо він вже є в JWT. Використовуйте /users/me/profile — це запобігає Insecure Direct Object Reference атакам.
- IDOR (Insecure Direct Object Reference) — атака, при якій зловмисник підміняє ID в URL (
/users/123→/users/124), отримуючи доступ до чужих даних. Захист: звіряти ID з URL з ID у JWT.
Продуктивність і Інфраструктура
- URI Length Limit: Браузери і проксі обмежують довжину URL. При занадто великій кількості фільтрів — переходьте з
GETнаPOST /_search - Matrix Parameters: Spring MVC підтримує
@MatrixVariableдля передачі параметрів у середину шляху
API Discovery
Добре спроектований API дозволяє викликати OPTIONS /users і отримати список доступних методів і параметрів. Це дозволяє клієнтам динамічно виявляти можливості API.
Edge Cases
- Якщо ресурс
/users/1існує, але ви викликалиPOSTзамістьGET— сервер має повернути 405 Method Not Allowed із заголовкомAllow: GET, PUT, DELETE. Повернення404— помилка дизайну - При інтеграції із зовнішніми системами документуйте всі можливі query-параметри
🎯 Шпаргалка для співбесіди
Обов’язково знати:
- URI — іменник у множині:
/users,/orders,/products - Kebab-case для URL:
/audit-logs,/user-profiles(RFC 3986) - Фільтрація через query-параметри:
/users?role=admin&status=active, не через ієрархію URI - Actions не-CRUD:
PATCH /users/1з тілом абоPOST /users/1/cancellation(resource-as-action) - Trailing Slash:
/users/і/users— різні ресурси; Spring Boot 3 робить 308 redirect - IDOR Prevention: використовувати
/users/me/profileзамість/users/{id}/profile, якщо ID вже у JWT - 405 Method Not Allowed із заголовком Allow — правильна відповідь, якщо метод не підходить (не 404)
Часті уточнюючі запитання:
- Як обробляти дії на кшталт «активувати»? — PATCH з
{"status": "ACTIVE"}або POST /users/1/activation - Що таке IDOR і як захиститися? — Підміна ID в URL; захист: звіряти ID з URL з ID у JWT
- Коли використовувати POST /_search замість GET? — При занадто великій кількості фільтрів (URL > 2048 символів)
- Що таке Matrix Parameters? — Рідко використовувані
URL;param=value, підтримуються через @MatrixVariable у Spring
Червоні прапорці (НЕ говорити):
- «Дієслова в URL — це нормально» — URI = іменник, дія = HTTP метод
- «404 — правильна відповідь для неподходящого методу» — потрібен 405 Method Not Allowed із заголовком Allow
- «Однина краща за множину» — множина — стандарт індустрії
- «
audit_logsабоuserProfilesв URL» — kebab-case (audit-logs) — стандарт для URL
Пов’язані теми:
- [[Що таке RESTful API дизайн]]
- [[Чи варто використовувати дієслова в URL]]
- [[Які основні HTTP методи використовуються в REST]]
- [[В чому різниця між 401 та 403]]
- [[Як організувати версіонування REST API]]