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 с некоторым содержанием, что означает: «Да, я получил ваше видео, и я над ним работаю; он будет готов где-то в будущем и будет доступен через ID 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
касается обработки как таковой . Это ничего не ставит в очередь. Это не заботится о получающемся видео. Ресурс является самой обработкой. Его можно вызвать один или несколько раз.