"Найкраща" практика для спокійного реагування на пошту


217

Тож нічого нового тут я просто намагаюся отримати дещо роз’яснення і не можу знайти жодного в інших публікаціях.

Я створюю новий ресурс спокійно, скажіть:

/books (POST)

з тілом:

{
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

Я знаю, що я повинен повернути 201 (Створений) із заголовком Location нового ресурсу:

Location: /books/12345

Питання, на яке я, здається, не можу відповісти, це те, що повинен повернути сервер в тілі.

Я часто робив такий тип відповіді:

{
  id: 12345,
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

Я зробив це з кількох причин:

  1. Я написав api для фронтальних рамок, як angularjs. У моєму конкретному випадку я використовую кутові ресурси, і мені часто потрібен лише ідентифікатор ресурсу, щоб знайти його. Якщо я не повернув ідентифікатор в тілі відповіді, мені потрібно було б розібрати його із заголовка Location.
  2. У GET усіх книг я зазвичай повертаю весь об'єкт не лише ідентифікатор. У цьому сенсі мій клієнтський код не повинен розрізняти, звідки взяти ідентифікатор (заголовок місцезнаходження або тіло).

Тепер я знаю, що я справді перебуваю в сірій зоні, але більшість людей кажуть, що повернення всього ресурсу - це «погана» практика. Але що робити, якщо сервер змінює / додає інформацію до ресурсу. Він, безумовно, додає ідентифікатор, але може також додати інші речі, такі як часова мітка. Якщо я не повертаю весь ресурс, чи справді краще зробити POST, повернути ідентифікатор, а потім дозволити клієнту виконати GET, щоб отримати новий ресурс.


Я особисто вважаю за краще порожнє тіло для відповідей на пошту. Чи не повинно значення заголовка RESTful Location бути URI (унікальний ідентифікатор ресурсу)? Тому, можливо, ви повинні використовувати його як ідентифікатор, а не розбирати його, щоб з'ясувати внутрішній ідентифікатор сервера. Споживачі IMO, RESTful API повинні орієнтуватися за наданими гіперпосиланнями, а не будувати шлях, здогадуючись, де певний сервер розміщує ресурси ... І зрештою, хіба клієнт вже не знає стан ресурсу, який він тільки що створив? повторюючи це шва витрачає мережеві ресурси.
ch4mp

1
Для створення / вставки, статус 201 - СТВОРЕНО, Місце заголовка → localhost: 8080 / співробітників / 1 (Дивіться: тут )
Hassan

Відповіді:


129

Повернення цілого об'єкта в оновлення не здасться дуже доречним, але я навряд чи бачу, чому повернення всього об’єкта при його створенні було б поганою практикою у звичайному випадку використання. Це було б корисно принаймні для того, щоб легко отримати ідентифікатор та отримати часові позначки, коли це доречно. Це насправді поведінка за замовчуванням, отримана під час риштування з рейками.

Я дійсно не бачу жодної переваги повернути лише ідентифікатор та зробити GET-запит після того, щоб отримати дані, які ви могли отримати за допомогою свого початкового POST.

У будь-якому випадку, поки ваш API є послідовним, я думаю, що вам слід вибрати образець, який найкраще відповідає вашим потребам. Не існує жодного правильного способу створення API REST, imo.


26
Я знаю, що це по-старому, але я можу навести переконливий аргумент щодо використання GET після вашого POST. У специфікації http / 1.1 будь-який історичний інструмент може ігнорувати налаштування кешу, передані назад з вашої відповіді GET ... тому, якщо ваш користувач використовує кнопку "назад" у браузері, щоб повернутися на цю сторінку після оновлення її з POST, вона може використовувати затхлий кешовані дані з оригінального GET. Тож якщо ви повторно використовуєте GET, ви можете оновити кеш і отримати кращий знімок того, як виглядала сторінка, коли вони вийшли ...
Затінено

8
@Shaded Якщо API призначений для використання також у додатках, то ваш аргумент для запиту двох запитів не має значення. Там ви зазвичай кешуєте дані, зберігаючи в пам'яті об'єкти типу моделі - що зазвичай робиться з відповіддю на POST-запити. Щодо браузерів, відповідь на запит POST насправді не шкодить, поки існує кінцева точка GET api.
Jeehut

Я передплачую те, що тут заявляє Даніель. Навіть якщо ви перевіряєте зрілі рамки, такі як Spring Data, вони завжди повертають весь об'єкт після його збереження. Я думаю, що це хороша практика, оскільки у вашому клієнті ви заощадите серверний перехід, щоб отримати ту саму інформацію
frandevel

205

Повернення нового об'єкта відповідає принципу REST "Уніфікований інтерфейс - маніпуляція ресурсами через представлення". Повний об'єкт - це подання нового стану об’єкта, який був створений.

Тут справді відмінна посилання на дизайн API, тут: Кращі практики для проектування прагматичного API RESTful

Він включає відповідь на ваше запитання тут: Оновлення та створення повинні повертати представлення ресурсів

Він говорить:

Щоб споживач API не потребував повторного звернення до API для оновленого представлення, попросіть API повернути оновлене (або створене) представлення як частину відповіді.

Здається мені досить прагматично, і це відповідає тому принципу REST, про який я згадував вище.


6
як щодо повернення всього набору відповідних об’єктів? таким чином можливе сортування може бути виконане на стороні сервера, і це полегшує реалізацію
фронтальних даних

2
Але ці найкращі практики не найкращі. Автор заявляє, що HATEOAS, який важливий так само, як і інші принципи, не повинен використовуватися, оскільки "він не готовий". HATEOAS ніколи не буде "готовий", тому що всі принципи RESTful - це лише принципи архітектурного проектування, а не конкретна реалізація. Цитується посилання стосується бачення автора щодо API RESTful, який зовсім не RESTful через падіння HATEOAS. Ось чому це не найкраща довідка :)
marcinn

1
@marcinn - ви зауважите, що в оригінальному запитанні були цитати навколо "Кращого", я думаю, тому що в цій галузі існує велика думка. Посилання, на яке я вказував, - це те, що я вважаю практичним. Якщо у вас є краща довідка, будь ласка, поділіться нею. Я завжди відкритий для того, щоб дізнатися більше.
grahamesd

@grahamesd Реалізація - це інша річ, яка є принципом / шаблоном архітектурного дизайну. Ніхто не може сподіватися, що HATEOAS колись буде готовий, але є ймовірність, що хтось створить реалізацію, прийнятну для багатьох. Vinay також писав про зіставлення методів http до URL-адрес та конкретних операцій (CRUD), заявив, що модифікація за допомогою префіксації URL-адрес є більш прагматичним, написав, що фільтрування за параметрами запиту - це шлях ... це добре, але все це мало робити з RESTful архітектурою. Він писав про якийсь контракт. Це добре для HTTP API, але не називайте його RESTful.
marcinn

@grahamesd Ось кілька дописів, що пояснюють це: - medium.com/@andrea.chiarelli/… - restfulapi.net
marcinn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.