Чи неправильно повертати 202 "Прийнято" у відповідь на HTTP GET?


89

У мене є набір ресурсів, уявлення яких створені ліниво. Обчислення для побудови цих подань можуть зайняти від кількох мілісекунд до кількох годин, залежно від навантаження сервера, конкретного ресурсу та фази Місяця.

Перший запит GET, отриманий для ресурсу, починає обчислення на сервері. Якщо обчислення завершується протягом декількох секунд, обчислюване подання повертається. В іншому випадку повертається код стану 202 "Прийнято", і клієнт повинен опитати ресурс, поки не стане доступним остаточне представлення.

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

Через обмежену пам'ять і величезний обсяг запитів, ні NIO, ні тривале опитування не є варіантом ( тобто я не можу тримати майже достатньо підключених з'єднань відкритим, навіть не можу навіть вмістити всі запити в пам'яті; один раз "кілька секунд" пройшли, я продовжую зайві запити). Подібним чином, обмеження клієнта такі, що вони не можуть обробляти зворотний виклик завершення. Нарешті, зауважте, що я не зацікавлений у створенні "фабричного" ресурсу, до якого відправляється POST, оскільки додаткові зворотні поїздки означають, що ми не виконуємо обмеження в режимі реального часу по частинах більше, ніж бажано (крім того, це додаткова складність; вигода від кешування).

Думаю, є певні суперечки щодо повернення коду статусу 202 "Прийнято" у відповідь на запит GET, оскільки я ніколи цього не бачив на практиці, а його найбільш інтуїтивне використання - у відповідь на небезпечні методи, але я ніколи виявив що-небудь конкретно знеохочувальне це. Більше того, я не зберігаю і безпеку, і неможливість?

Отже, що люди думають про цей підхід?

EDIT : Я повинен згадати, що це для так званого бізнес-веб-API, а не для браузерів.


2
Я особисто вважаю, що це добре, це саме визначення поняття 202. Те, що це рідко використовується на практиці, більше стосується IMHO, оскільки мало хто з розробників веб-сайтів дбає про належні коди стану, оскільки вони більше звикли до взаємодії браузер / користувач-агент, і в цьому випадку a не 202дає їм видимого підказки (дайте їм, 200і вони щасливі. ..).
Wrikken

1
@ user359996, просто використовуйте 200. 202це те, що повинно бути, але на практиці люди не очікують 202.
Pacerier

йому потрібен ETA для 200, щоб бути корисним на практиці.
Роб

Відповіді:


66

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

Якщо це для загальнодоступного Інтернету, я б надто хвилювався щодо сумісності клієнтів. Я бачив стільки if (status == 200)твердокодованих .... У такому випадку я б повернув a 200.

Крім того, RFC не вказує на те, що використання 202 для запиту GET є неправильним, тоді як він чітко розрізняє інші описи коду (наприклад, 200).

Запит прийнято до обробки, але обробка не завершена.


16

Ми зробили це для нещодавньої програми, клієнт (спеціальна програма, а не браузер) POST'зав запит, і сервер поверне 202 із URI на "роботу", що розміщується - клієнт використовує цей URI для опитування для результат - здається, це добре відповідає тому, що робилося.

Найголовніше тут - це так чи інакше задокументувати, як працює ваш сервіс / API, і що означає відповідь 202.


+1 Дякую за ваш коментар. Хороший момент щодо документації. Але, будь ласка, зверніть увагу на уточнюючі редагування мого запитання (шукайте "фабрика").
user359996

Ну, ви можете опустити цей URI у відповіді, якщо ви просто хочете опитати той самий URI, який ви фактично просили. (Просто задокументуйте, як це має працювати :-))
No

Хороша ідея, але пам’ятайте, що я хочу кешувати, тому POST немає. Більше того, URI визначає ресурс, а не метод. Я використовую підхід RESTful, а не RPC (вибачте, ще одне невизначене обмеження - моє погане).
user359996

Точніше кажучи, під "RESTful" я насправді маю на увазі "орієнтований на ресурси", що технічно трохи більше, ніж визначено обмеженнями REST.
user359996

12

З того, що я можу згадати - GET повинен повертати ресурс без зміни сервера. Можливо, діяльність буде зареєстрована або що у вас є, але запит слід повторити з тим самим результатом.

POST, з іншого боку, - це запит змінити стан чогось на сервері. Вставте запис, видаліть запис, запустіть завдання, щось подібне. 202 було б доречним для POST, який повернувся, але не закінчив, але насправді не є запитом GET.

Це все дуже пуритано і погано практикується в дикій природі, тому ви, мабуть, у безпеці, повернувши 202. GET повинен повернути 200. POST може повернути 200, якщо все закінчилося, або 202, якщо цього не зроблено.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html


4
Дуже добре думаю, але я не впевнений, чи застосовується це тут: З огляду на те, що каже OP, це, здається, правильний запит GET (оскільки він нічого не змінює на сервері), просто потрібно більше часу для обчислення та цей випадок повинен бути завантажений в інший час. Можливо, ОП може дати авторитетний коментар. Це для API, тому чудово бути "пуританом" заради чистого інтерфейсу
Pekka

О, дотик пекка. Ви маєте рацію, GET - це шлях. І я не думаю, що HTTP spc дійсно враховував GET, які не готові. Тож він міг піти в будь-який бік
Длонгнекер

7
(Зараз - неактуальний) авторитетний коментар: Так, я розглядаю це як ідемпотент. Ресурс не є ні модифікується , ні створений, а це уявлення ще не було обчислено.
user359996

1
Де це сказано? Крім того, якщо я поверну 200, клієнт повинен очікувати, що подання було повернуто, але це не так.
user359996

1
Я беру його назад. 202, здається, не відповідає лише GET або POST. Тільки мислення, яким я займався, коли я дивився на протокол, зробило так, що 202 існувало лише для запитів GET. 202 має відповідати вашим цілям.
Длонгнекер,

0

У випадку ресурсу, який повинен мати подання сутності, яка чітко вказана ідентифікатором (на відміну від "фабричного" ресурсу, як описано у питанні), я рекомендую дотримуватися методу GET і, в Ситуація, коли сутність / представництво недоступні через ледаче створення чи будь-яку іншу тимчасову ситуацію, використовуйте код відповіді 503 Недоступний сервіс, який є більш підходящим і фактично розроблений для таких ситуацій, як ця.

Обгрунтування цього можна знайти в RFC для самого HTTP (перевірте опис коду відповіді 503), а також у багатьох інших ресурсах.

Порівняйте із кодом стану HTTP для тимчасово недоступних сторінок . Хоча це питання стосується іншого варіанту використання, насправді воно стосується точно тієї ж функції HTTP.

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