1. Использовать множественное число для коллекций
✅ GET /products
✅ GET /products/{product_id}
❌ GET /product/{product_id}
2. Не добавлять лишние сегменты в путь
✅ GET /v3/application/listings/{listing_id}
❌ PATCH /v3/application/shops/{shop_id}/listings/{listing_id}
Не пытаться отразить всю модель данных в URL
Если
listing_id уникален — shop_id не нужен💙 Исключение: если ключ действительно составной
GET /listings/{listing_id}/options/{option_id}3. Не добавлять расширения в URL
❌
GET /users.json Формат передачи должен определяться через HTTP-заголовки (например,
Accept) , не через URL✅
GET /users и HTTP-заголовки настройка заголовков:Accept: application/json
4. Не возвращать массивы верхнего уровня
Объект позволяет легко добавить пагинацию и дополнительные поля без поломки обратной совместимости
❌
[{"id":1}, {"id":2}]✅
{ "data": [{"id":1}, {"id":2}] }5. Не возвращать структуры-словари (map)
Словари ломают совместимость и неудобны для типизированных языков.
💙 Исключение: простые пары ключ: значение (например, metadata)
✅
{ "data": [{ "id":"KEY1" }, { "id":"KEY2" }] }❌ { "KEY1": {...}, "KEY2": {...} }
6. Добавлять префиксы к ID
✅ Помогает отличать типы сущностей и уменьшает путаницу при поддержке
Примеры:
Stripe: in_1MVpWEJVZPfyS2HyRgVDkwiZ
Shopify: gid://shopify/FulfillmentOrder/1469358604360
7. Не использовать 404 для “не найдено”
❌
404 Not Found может означать сетевую ошибку или неверный URL🔹может быть возвращен прокси, балансировщиком нагрузки и т.д.
🔹не позволяет клиенту отличить "ресурс не существует" от "ошибка конфигурации"
✅ Использовать, например,
410 Gone — сервер понял запрос, но объекта нет8. Ошибки в структурированном формате
✅Позволяет передавать цепочку ошибок и упрощает отладку
{
"message": "Access denied",
"type": "Unauthorized",
"types": ["Unauthorized", "Security"],
"cause": { ... }
}9. Идемпотентность операций
Идемпотентность = повтор вызова не меняет результат
🔹 GET, PUT, DELETE — по определению идемпотентны
🔹 Для POST добавлять идемпотентный ключ: клиент отправляет уникальный ключ в заголовке или теле, а сервер проверяет его уникальность
POST /orders
Idempotency-Key: abc123
Если запрос повторится — сервер вернёт 409 CONFLICT и ID уже созданного ресурса:
{
"message": "Duplicate",
"old_id": "ORD123"
}Клиент уверен, что заказ не задублировался
10. ISO8601 для даты и времени
А также использовать ISO8601 для интервалов и длительностей
✅
"2023-12-21T11:17:12.34Z" ❌
"1703157432340"🔹ISO8601 человеко-читаем
🔹поддерживается всеми библиотеками
🔹работает в UTC
#api
➿➿➿➿➿➿➿➿
🧑🎓 Больше полезного в базе знаний по системному анализу