Прийнято HTTP 202 (HTTP / 1.1)
Ви шукаєте HTTP 202 Accepted
статус. Див. RFC 2616 :
Запит прийнято для обробки, але обробка не завершена.
Обробка HTTP 102 (WebDAV)
RFC 2518 пропонує використовувати HTTP 102 Processing
:
Код стану 102 (Обробка) - проміжна відповідь, яка використовується для інформування клієнта про те, що сервер прийняв повний запит, але ще не виконав його.
але він має застереження:
Сервер ПОВИНЕН надіслати остаточну відповідь після завершення запиту.
Я не впевнений, як інтерпретувати останнє речення. Чи повинен сервер уникати нічого надсилання під час обробки та відповідати лише після його завершення? Або це лише примушує припинити відповідь лише тоді, коли обробка закінчується? Це може бути корисно, якщо ви хочете повідомити про прогрес. Надішліть HTTP 102 і обведіть байт відповіді за байтом (або рядком за рядком).
Наприклад, для тривалого, але лінійного процесу ви можете надіслати сто крапок, промиваючи після кожного символу. Якщо клієнтська сторона (наприклад, програма JavaScript) знає, що вона повинна очікувати рівно 100 символів, вона може співставити її з панеллю прогресу, яка буде показана користувачеві.
Інший приклад стосується процесу, який складається з декількох нелінійних етапів. Після кожного кроку ви можете обмивати повідомлення журналу, яке згодом відображатиметься користувачеві, щоб кінцевий користувач міг знати, як відбувається процес.
Проблеми з прогресивним промиванням
Зауважте, що хоча ця методика має свої достоїнства, я б не рекомендував її . Однією з причин є те, що воно змушує зв’язок залишатися відкритим, що може зашкодити з точки зору доступності послуги та не змінювати масштаби.
Кращим підходом є відповідь HTTP 202 Accepted
і або дозволити користувачеві повернутися до вас пізніше, щоб визначити, чи закінчилася обробка (наприклад, повторним викликом даного URI, такого, /process/result
який би відповів HTTP 404 Not Found або HTTP 409 Conflict до процесу завершується, і результат готовий), або повідомляйте користувача, коли обробка завершена, якщо ви зможете зателефонувати клієнту, наприклад, через службу черги повідомлень ( приклад ) або WebSockets.
Практичний приклад
Уявіть веб-сервіс, який конвертує відео. Точка входу:
POST /video/convert
який бере відео-файл із HTTP-запиту і виконує з ним деяку магію. Давайте уявимо, що магія є інтенсивною процесором, тому її неможливо зробити в режимі реального часу під час передачі запиту. Це означає, що щойно файл буде передано, сервер відповість на нього HTTP 202 Accepted
з деяким вмістом JSON, тобто "Так, я отримав ваше відео, і я працюю над ним; він буде готовий десь у майбутньому та буде доступний через ідентифікатор 123. "
Клієнт має можливість підписатися на чергу повідомлень, про яку буде повідомлено, коли обробка закінчиться. Після її завершення клієнт може завантажити оброблене відео, перейшовши до:
GET /video/download/123
що призводить до ан HTTP 200
.
Що станеться, якщо клієнт запитує цей URI, перш ніж отримувати сповіщення? Ну, сервер відповість, HTTP 404
оскільки, справді, відео ще не існує. Наразі вона може бути підготовлена. Це може ніколи не просити. Він може існувати певний час в минулому і бути видалений пізніше. Важливо лише те, що отримане відео недоступне.
Тепер, що робити, якщо клієнт дбає не лише про остаточне відео, а й про прогрес (що було б ще важливіше, якщо немає служби черги повідомлень чи будь-якого подібного механізму)?
У цьому випадку ви можете використовувати іншу кінцеву точку:
GET /video/status/123
що призведе до подібної відповіді:
HTTP 200
{
"id": 123,
"status": "queued",
"priority": 2,
"progress-percent": 0,
"submitted-utc-time": "2016-04-19T13:59:22"
}
Виконання запиту знову і знову покаже прогрес, поки він не стане:
HTTP 200
{
"id": 123,
"status": "done",
"progress-percent": 100,
"submitted-utc-time": "2016-04-19T13:59:22"
}
Важливо змінити ці три типи запитів:
POST /video/convert
черги завдання. Його слід викликати лише один раз: зателефонувавши ще раз, це поставило б чергу в додаткове завдання.
GET /video/download/123
стосується результату операції: ресурсом є відео. Обробка - ось що сталося під кришкою для підготовки фактичного результату до запиту та незалежно від запиту - тут не має значення. Його можна викликати один або кілька разів.
GET /video/status/123
стосується обробки як такої . Він нічого не чергає. Це не хвилює отримане відео. Ресурс є найбільш обробкою. Його можна викликати один або кілька разів.