Чи повинен API HTTP завжди повертати тіло?


33

Чи існує якийсь стандарт щодо відповідей HTTP API?

Прочитавши цю тему дискурсу, я задумався. Ми розробляємо наш публічний API HTTP JSON під час моєї роботи, і ми нічого не повертаємо, коли це не потрібно строго (наприклад, PUT в / Resource / {id} повертає 200 лише в порядку, або відповідний код 4XX або 5XX, але ні Корпус JSON)

Чи повинні ми повернути загальне, {"success":true}як вони обговорюють на цьому посиланні вище, або це нормально, щоб повернути тіло "void" і обробити все за допомогою кодів відповідей http?


8
{"успіх": true} здається зайвим. Спробуйте краще використовувати HTTP-коди. w3.org/Protocols/rfc2616/rfc2616-sec9.html
CodeART

HTTP 1.1 представляє HEAD, якому не вистачає корпусу, це лише відповідь заголовків GET.
боктул

Відповіді:


28

Що стосується PUT, але застосовується і до POST. Специфікації HTTP розділ 9 трохи порожньо за правилами або навіть поради (повинні) , коли мова йде про сценарій , який ви описуєте. Рядок, що відповідає вашому питанню, найбільше охоплює:

Якщо створено новий ресурс, сервер-джерело ОБОВ'ЯЗКОВО повідомить про це агента користувача через відповідь 201 (Створено). Якщо існуючий ресурс модифікований, або відповідатимуть коди відповідей 200 (ОК) або 204 (Без вмісту), щоб вказати на успішне виконання запиту.

Я не думаю, що я втрачу сон над цим, але я б запитав, що ви отримуєте, додаючи шматочок JSON у відповідь? Ви тільки що накопичили (Гаразд, об'єм може бути надмірним!), Відповідь повторює менш точно те, що код статусу вже повинен був вам сказати. Якщо ваш PUT призвів до повернення нового об'єкта 201 (як це має намір PUT), якщо він оновив повернення об'єкта 204.

До речі, API убік, а не 200, якщо ви нічого не повернете, використовуйте 204.

Якщо припустити, що ви розробляєте набір інтерфейсів RESTful, стандартів сам по собі не існує, тому що б ви не зробили, добре документуйте його, надайте приклади, і все буде добре.


2
З POST, ви, ймовірно, захочете відповісти ідентифікатором ресурсу, який може використовуватися для подальшого маніпулювання ним. POST /resource-> { "self" : "/resource/5" }.
Гей,

1
@Hey, я б використовував для цього locationзаголовок http.
CodesInChaos

@CodesInChaos Так, це абсолютно законно, хоча я ніколи насправді не бачив, як це робилося на практиці, і, мабуть, не віддав би перевагу цьому споживачам.
Гей,

1
Випадок використання полягає в тому, що клієнт очікує дійсного JSON, навіть якщо відповідь "порожній" або не містить вмісту. Хороший приклад - JQuery, про який Абхі згадував нижче.
B Сім

12

Базовий стандарт HTTP не передбачає наявності документа, повернутого у відповідь. Заради економії, коли статус HTTP передає все необхідне, організм буде марним. Однак є стандарти, побудовані поверх HTTP, які додають нові правила.

Існує відкритий стандарт JSON API, який визначає:

  • Об'єкт JSON ОБОВ'ЯЗКОВО знаходиться в корені кожного документа відповіді API JSON . (Курсив відображає те, що я додав для уточнення тексту)

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

Деякі програми (наприклад, ElasticSearch ) надають повний api-файл JSON і завжди мають деякі метадані, щоб ви могли краще уявити, як сервер управляє вашими даними. Стандартний об'єкт відповідей повідомляє вам про стан індексу, якщо запит призвів до помилки, на скільки впливали вузли тощо. ElasticSearch використовує "application / json" для типу mime, тому навряд чи вони застосовують вказівки в стандарт jsonapi.org.

JQuery і подібні рамки Javascript припускають, що завжди буде документ. Питання полягає в тому, скільки перевірки помилок ви хочете застосувати до споживачів API? Якщо ви запропонували стандартний формат для всіх відповідей, який розширюється лише залежно від типу запиту, ви задовольняєте потребу у поверненому документі та можете полегшити налагодження вашими споживачами API.


1
Це. Коли я надсилаю запит на сервер API JSON, перше, що я повинен зробити, це перевірити, чи відповідь є дійсною JSON. Якщо він недійсний, я вважаю, що запит не вдався, навіть якщо я отримав відповідь 200. Пустий відповідь / рядок недійсний JSON.
Абхі Беккерт

5

Ні, наприклад, для 204 відповідей ми не повинні включати тіло повідомлення. {успіх | статус | isSupcessful: true} є зайвим.

На практиці (чи слід сказати в пізнішій версії jquery) порожня відповідь для типу вмісту application / json викликає помилку. Я начебто розумію аргумент, що оскільки це application / json, він повинен мати дійсне тіло json. Отже, порожня відповідь для типу вмісту application / json буде "null" або "{}", що є json.

Існує ще один спосіб, який повинен працювати для jquery, це не повернення програми / json для порожніх відповідей. Просто використовуйте текст / звичайний текст або щось подібне і переконайтеся, що клієнт може впоратися з цим типом.

Примітка. Я пам'ятаю лише 204, щоб явно заборонити повертати тіло повідомлення. Що ми знайшли, це те, що ми не завжди можемо використовувати 204. Проблема полягає в заголовку відповіді на перепад MSIE для 204 відповідей, тому немає вмісту та заголовків, що погано. Оскільки багато хто використовує MSIE, нам довелося змінити його на 200 статусів.


3

Ні, але це допоможе для узгодженості вашого коду. Це також добре для налагодження. Це також допоможе у підтримці веб-сайту. Пам'ятайте це: код помилки призначений для машини, повідомлення про помилку - для людини. Тому я пропоную вам скористатись органом реагування. У будь-якому випадку, його негативний ефект просто мінімальний (всього кілька байт, що надсилаються по мережі) порівняно з його перевагами. Інша справа, це також дозволить вам не забути написати тіло повідомлення, коли це потрібно.


3

Я б не повертав просто статус успіху у відповіді, код помилки http лише сигналізує про успіх чи помилку. Я б включав лише використання самої відповіді, щоб додати детальну інформацію про помилки, таку як конкретні програми помилок або повідомлення про помилки.

Для запитів PUT, PATCH та POST ти, як правило, повертає стан повернення стану ресурсу після застосування запиту, а не порожньої відповіді.

Для запитів POST, що представляють собою дію, а не просто створення ресурсу (не дуже RESTful, але все ще корисний на практиці), який не має корисних даних для повернення, я б повернув відповідь, що складається з порожнього об'єкта json, тобто {}. Таким чином клієнт отримує вагому відповідь, і додавання трохи інформації пізніше, навряд чи це порушить.

Для DELETE запитів, що повертають 204, і порожнє тіло є досить поширеним явищем, що має сенс, оскільки ресурс після цього не існує.


2

Я б запропонував повернути лише те, що потрібно + невелике уточнення.

Наприклад, залежно від способу використання вашого API, ви можете включити копію об'єкта, яка існує після збереження.

Отже, POST {key: 123} може повернутися {key: 123, foo: 'bar'}.

Основна ідея: краще повернути об’єкт, а потім знову за ним запитати.

Однак, вашим споживачам API не потрібен об'єкт, повертати його не потрібно.

Зазвичай я повертаюсь {success: true} або щось подібне, коли для POST PUT і PATCH немає необхідного об'єкта, оскільки це полегшує кінець прийому. Однак, краще 99% часу повернути збережене представлення об'єкта; рідко вони їм не знадобляться, і "дешевше" відправити все це за один запит, а потім за два.

Щоб бути конкретним, в лабораторії ідеально знайти все, що працює лише з кодами статусу, в реальному світі набагато краще повернути деякі дані, навіть якщо вони є зайвими, так що споживачі API можуть легко зрозуміти, що намагаються сказати.

Повернення 200 {success: true} дозволяє людям писати код обома способами:

if response.code == 200
  do stuff
end

і

if response.body.success
  do stuff
end

до того ж це не так важко зробити на вашому боці.

Нарешті, (вибачте за структуру відповідей poos), надаючи загальнодоступному JSON api, що ви відмовились від великого контролю над тим, як це буде використовуватися. Деякі клієнти можуть реагувати по-різному на різні органи (або їх відсутні) або коди статусу.


+1 за "отримати лише те, що потрібно (і не більше)"
Niklas Rosencrantz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.