Считается ли HTTP 303 опасным для асинхронных операций?

При исследовании RESTful API для асинхронных операций я столкнулся со следующим шаблоном проектирования:

POST uri:longOperation возвращает:

  • HTTP 202
  • Расположение: uri:pendingOperation

GET uri:pendingOperation возвращает:

  • If operation is running
    • Return a progress report.
  • If operation is complete
    • HTTP 303
    • Расположение: uri:operationResponse

GET uri:operationResponse

  • Ответ асинхронной операции

Я нахожу последний шаг сомнительным. Подумайте, что произойдет, если асинхронная операция завершится с кодом ошибки, который не имеет смысла для HTTP GET, например HTTP 409 ("Conflict").

  1. Разве HTTP 303 не должен указывать на ответ, связанный с uri:pendingOperation, а не на uri:operationResponse?
  2. Считается ли использование HTTP 303 таким образом вредным? Если нет, то почему?
  3. Это лучшее, что мы можем сделать, или есть лучший способ?

person Gili    schedule 13.12.2012    source источник


Ответы (1)


Разве HTTP 303 не должен указывать на ответ, связанный с uri:pendingOperation, а не на uri:operationResponse?

В спецификации прямо не указано, что это требуется, но я склонен с вами согласиться.

Считается ли использование HTTP 303 таким образом вредным? Если нет, то почему?

Я думаю, что вы теряете возможности, выполняя 303. Хотя «приятно» автоматически перенаправлять, когда это сделано, это делает так, что у вас нет возможности предоставить метаданные о результатах, которые можно использовать для отчетности и т. д. ... Также многие клиенты не следят за 303 автоматически, поэтому клиенту, возможно, придется выполнить работу, чтобы в любом случае следовать заголовку 303 Location.

Это лучшее, что мы можем сделать, или есть лучший способ?

Я склонен рекомендовать, чтобы GET uri:pendingOperation возвращал 200 с ресурсом состояния всегда со ссылкой на вывод, когда он «завершен». Что-то типа

Когда не завершено

{
    "status" : "PENDING"
}

Когда ошибка

{
    "status" : "COMPLETE"
    "errors" : [
       {
          "typeId" : "OPERATION_TIMEOUT",
          "description" : " "The request was unable to complete because the systems are unresponsive".
       }
    ]
}

Когда успешно

{
    "status" : "COMPLETE"
    "links" : {
       "result" : {
          "href" : "http://api.example.com/finished-resource/1234",
       }
    ]
}

person Daniel Roop    schedule 02.02.2013