“준비되지 않았지만 나중에 다시 시도하십시오”에 대해 REST API에서 HTTP 상태 코드를 어떻게 선택합니까? [닫은]


152

http://server/thingyapi/thingyblob/1234다운로드 할 항목 # 1234와 관련된 파일 (일명 "blob") 을 반환 하는 RESTful API를 개발 중 입니다. 그러나 파일이 서버에 존재하지 않을 때 요청이 이루어 지지만 나중에 가장 확실 하게 사용 가능할 수 있습니다. 서버에는 모든 것들에 대한 모든 얼룩을 생성하는 배치 프로세스가 있습니다. Thingy 1234가 이미 존재하고 Blob 이외의 데이터가 이미 사용 가능합니다. 서버는 아직 1234의 Blob을 생성하지 않아도됩니다.

404를 반환하고 싶지 않습니다. 그것은 존재하지 않는 것들을위한 것입니다. 이것은 존재하지만 그 얼룩은 아직 생성되지 않은 것입니다. "처리 중"인 YouTube 동영상을 좋아합니다. 리디렉션 코드도 적절하지 않다고 생각합니다. 시도 할 "다른"URL이 없습니다.

이 경우 올바른 HTTP 상태 코드는 무엇입니까?



7
첫째, 1234가 아직 GET 가능 표현을 가지고 있지 않다면 어떤 의미에서 (클라이언트의 관점에서) 자원으로서 존재 하는가? 1234를 작성하기 위해 대기중인 작업이 서버 내부에 있다는 사실이 1234 자원이 존재한다는 것을 의미하지는 않습니다. 둘째, 클라이언트는 URI ... / thingyblob / 1234를 어디서 얻었습니까? 서버는 리소스가 실제로 GET 가능할 때까지 해당 URI를 클라이언트에 제공하지 않았을 것입니다.
Andy Dennie

1
물건에는 얼룩 이외의 가치가있는 다른 속성이 있습니다. 생성하는 데 시간이 걸리는 것은 블롭뿐입니다. 고객은 예를 들어 server / thingyapi / thingy / 1234
JCCyC

10
HTTP 표준은 어떤 상황에서 어떤 상태 코드를 사용해야하는지에 대한 지침을 제공합니다. 따라서이 질문은 실제로 주로 의견 기반이 아닙니다 .
Raedwald

2
방법에 대해 204"아니오 내용"? Is는 서버가 요청을 성공적으로 처리했으며 [현재] 콘텐츠를 반환하지 않음을 나타냅니다.
Timo

답변:


77

나는 제안한다 202 - Accepted. 로부터 문서 :

요청이 처리를 위해 승인되었지만 처리가 완료되지 않았습니다. [...] 그 목적은 서버가 다른 프로세스 (아마도 하루에 한 번만 실행되는 배치 지향 프로세스)에 대한 요청을 수락하도록하는 것입니다.


62
-1 : 이것은 결국 "thingy # 1234"자체를 위해 발행 된 GET 요청에는 적용되지 않지만 결국 "thingy # 1234"를 생성하는 프로세스를 시작하는 요청에 적합합니다. 특히, 202는 GET 요청의 결과로, 서비스가 나중에 "thingy # 1234"에 대한 데이터를 전송할 것을 제안한다. 이것은 단순히 정확하지 않습니다.
Sam Harwell

7
또한 "이 응답과 함께 반환 된 엔터티에는 요청의 현재 상태 표시와 상태 모니터에 대한 포인터 또는 사용자가 요청이 이행 될 것으로 예상 할 수있는 시간의 추정치가 포함되어야합니다." 클라이언트에게 블롭이 아직 준비되지 않았다는 것을 알리는 좋은 방법과 언제 준비되었는지 알 수있는 좋은 방법입니다.
Remy Lebeau

3
"처리 승인"은 나중에 처리 할 요청을 저장하고 있음을 나타냅니다. 방금 무시되는 경우 4xx 또는 5xx 코드를 반환하여 클라이언트에게 다시 시도 할 수 있음을 나타냅니다.
Luke

3
102 (프로세싱)도 때로는 webdav 사양에 있지만 합리적인 선택으로 보입니다.
akostadinov

2
이 답변에 더 이상 동의하지 않습니다. 서버가 아무것도 반환하지 않거나 계획하지 않습니다 (이 요청으로 인해 처리하지 않음-어쨌든 GET해서는 안 됨). 따라서 리소스는 어떤 방식으로 클라이언트가 사용할 수 없습니다. 이는 2XX 코드가 적절하지 않도록 오류로 처리해야합니다. 4XX 또는 5XX 공간에 있습니다. 요청이 "처리가 승인 되지 않았습니다 " , 요청이 실제로 폐기 됨
Adam

52

"문제"는 서버 측에 있습니다. 클라이언트가 올바른 형식의 요청을했지만 서버가이를 충족시킬 수 없습니다. 그래서 나는 "서버 오류", 5xx 상태 코드에 관심이 있습니다.

Quoth RFC 7231 (현재 HTTP 표준, 강조 추가) :

5xx (서버 오류) 상태 코드 클래스는 서버가 서버가 요청 된 메소드를 잘못 했거나 수행 할 수 없음을 인식하고 있음을 나타냅니다 . HEAD 요청에 응답 할 때를 제외하고, 서버는 오류 상황에 대한 설명과 일시적 또는 영구 조건 인지 여부를 포함하는 표현을 보내야합니다 .

노트

  • " 요청을 수행 할 수 없거나 오류 가 발생했습니다": "서버 오류"라는 제목에도 불구하고 서버 오류만을위한 것이 아닙니다.
  • " 임시 또는 영구":이 코드는 귀하와 같은 일시적으로 사용할 수없는 리소스에 적합합니다.

사용 가능한 코드 중에서 503은 "서비스를 사용할 수 없음" 이 가장 적합 하다고 말합니다 .

503 (Service Unavailable) 상태 코드는 서버가 일시적 과부하 또는 예정된 유지 보수로 인해 현재 요청을 처리 할 수 ​​없음을 나타냅니다. 이는 약간의 지연 후에 완화 될 수 있습니다. 서버는 Retry-After 헤더 필드를 보내서 요청을 재 시도하기 전에 클라이언트가 기다리는 시간을 제안 할 수 있습니다.

노트 :

  • "약간의 지연 후에 완화 될 수 있습니다": 귀하의 경우에는 해당됩니다.
  • "임시 과부하": 귀하의 경우에는 사실이 아닙니다. 그러나이 주장 할 수있는, 클라이언트가 요청을하면 서버가 훨씬 더 빨리, 일괄 처리가 이미 있으므로, 수행했을했다 입니다 클라이언트가 할 수 빨리 서버가 아닌 리소스를 요구하고있다 "과부하"의 종류 사용할 수 있습니다.
  • 재 시도는 서비스에 적합하므로 회신에 Retry-After값 이 포함되어야 합니다. 다음 일괄 프로세스 실행의 예상 완료 시간 또는 일괄 프로세스의 실행 간격을 값으로 제공 할 수 있습니다.

허용 되지만 자신의 5xx 상태 코드 (예 : 591)를 정의 하면 잘못된 의미가 있습니다.

클라이언트는 첫 번째 숫자로 표시되는 모든 상태 코드의 클래스를 이해하고 인식 할 수없는 상태 코드를 해당 클래스의 x00 상태 코드와 동등한 것으로 취급해야합니다.

클라이언트는 자신의 상태 코드를 500, "내부 서버 오류" 로 취급합니다 .


2
나는 그것이 202보다 낫다는 것을 알지 못한다
JCCyC

4
@JCCyC 블로그는 무언가 (POST 또는 PUT) 생성 요청에 대한 응답으로 202를 반환하는 좋은 사례를 만듭니다. 문제는 GET을 위해 무엇을 반환해야하는지 묻는 것 같습니다.
Raedwald

@JCCyC 그것은 준비되지 않은 다른 그늘로 보일 수 있습니다 : 그 자원에 대한 아약스를 상상해보십시오. 성공 상태로 202를, 오류 상태로 503을 선호합니까? 응답에 대한 앱의 반응에서 암시 적으로 선호하는 의미를 알 수 있습니다
rloth

또한 "준비되지 않은"것과 잘 어울리는 "다시 시도"의 실제적인 측면을 좋아합니다
rloth

1
NB : "재시도 후"는 307 - TEMPORARY REDIRECT자원이 "준비"되어있는 동안 클라이언트 측이 다른 곳에서 대기하도록하려는 경우 에도 좋습니다.
rloth

28

나는 423-Locked 가이 목적으로 사용될 수 있다고 생각합니다 .

423 (Locked) 상태 코드는 메소드의 소스 또는 대상 자원이 잠겨 있음을 의미합니다. 이 응답에는 '잠금 토큰 제출'또는 '충돌 방지 잠금'과 같은 적절한 사전 조건 또는 사후 조건 코드가 포함되어야합니다.


1
훌륭한 답변! 왜 더 많은 투표가 없는지 궁금합니다.
lex82

10
아마도 WebDAV HTTP 코드이기 때문일까요?
Stephan L

1
akka-http에는 StatusCode RetryWith = reg (c (449) ( "재시도", "적절한 조치를 수행 한 후 요청을 재 시도해야합니다."))가 있으며 조치가 대기하고 재 시도되는 곳
ozma

2
여러면에서 나는 이것에 동의합니다. 비슷한 상황이 있습니다 (필자의 경우 아직 채워지지 않은 색인에서 검색하는 경우). 의미 상으로는 이것이 맞다고 생각합니다. 그러나 423에 대한 RFC는 "이 응답에는 '잠금 토큰 제출'또는 '충돌 방지 잠금'과 같은 적절한 사전 조건 또는 사후 조건 코드가 포함되어야합니다." 그것을 적용하는 방법을 잘 모르겠습니다. 그리고 개인적으로 나는 409 Conflict와 함께 갈 것입니다.하지만 그것은 의견없이 downvoted되었습니다. 왜 그런지 확실하지 않습니까?
Adam

22

404를 반환하고 싶지 않습니다. 그것은 존재하지 않는 것들을위한 것입니다.

URL이 사물 요청에 해당하지 않습니다.

http://server/thingyapi/thingyblob/1234

클라이언트가 존재하지 않는 상황을 요청하고 있습니다. 그것이 존재한다면, 당신은 그들에게 줄 것입니다.

404.


1
나는 누군가가 이것을 말했기 때문에 기쁘다! 503적절한 반응 이라고 생각 하는 사람들이 너무 많다는 것을 믿을 수 없습니다 . 다른 이상한 제안은 말할 것도 없습니다.
Jason Desrosiers

여기에서 404가 가장 적합한 응답이지만 동의하는 경우 언제 사용할 수 있는지 나타내는 방법은 OP의 질문에 대답하지 않습니다. :-). Retry-After 필드가 가장 적합한 후보라고 생각하지만 공식적으로 503 및 3xx 코드에만 사용할 수 있습니다. @ 제이슨 : 나는 그것이 이상한 제안을 설명한다고 생각합니다.
Ron Deijkers

이것이 가장 좋은 대답이라고 생각합니다. 404 응답으로 본문을 반환 할 수 있습니다. 시체는 나중에 물건을 구입할 수 있다고 지시 할 수 있습니다. 또는 Retry-After 헤더도 사용하십시오. 이 사례를 잘 다루지 않기 때문에 표준을 약간 늘려야합니다.
WW.

4
사람들은 API의 맥락에서 논리적으로 분리 할 수 ​​없다는 페이지를 발견하지 못하여 404에 너무 익숙해졌습니다.
머핀 맨

1
이것은 sooooo 404입니다. Thingyblob은 (는) 아직 존재하지 않습니다. 현재로서는 존재하지 않으며 404입니다. 사용 가능할 때 또 다른 문제가 있습니다.이 문제는 서버에서 클라이언트로 thingyblob : 1234 사용 가능으로 메시지를 푸시하여 해결할 수 있습니다. 다시 가져와 voila를 수행하십시오.
100r

21

다른 옵션 : 503 - Service Unavailable.


5
W3C에 따르면 클라이언트에게 말하고 싶은 것이 아닙니다 (어떤 방식 으로든 "다시 오십시오"를 의미하지만). 알려진 경우 지연 시간이 Retry-After 헤더에 표시 될 수 있습니다 Retry-After가 제공되지 않으면 클라이언트는 응답을 처리해야합니다. 500 답변. "
skalee

4
서비스를 사용할 수없고 서비스를 사용할 수 있지만 처리가 완료되지 않았습니다. 따라서 503은 좋은 생각이 아닙니다.
Ishtiaque Khan

17

리소스가 준비되지 않았으므로 리소스를 사용할 수있는시기와 클라이언트가 요청을 다시 시도 할 수있는시기를 알 수 있습니다. 즉, Retry-After header 를 사용할 수 있습니다 . 이 헤더는 503 (서비스를 사용할 수 없음)과 함께 유효합니다. 즉, 유지 관리를 위해 전체 사이트가 다운되었으며 3xx (리디렉션) 응답입니다.

내 의견으로는 Retry-After 헤더가있는 302 (Found)가 가장 좋은 옵션이지만 응답 헤더의 Location 필드가 url을 요청할 수 있는지 확실하지 않습니다. 어쨌든 순환 리디렉션입니다.


3
허용되는 경우에도 클라이언트가 Retry-After 헤더에 대한 지원을 구현하지 않은 경우 동일한 페이지로의 3xx 리디렉션은 결국 503으로 끝날 수 있습니다 (선택적으로 Retry-After 헤더와 함께)
Ron Deijkers

1
Retry-After는 RFC 6585 (2012 년 4 월)에 의해 추가 된 HTTP 429 "너무 많은 요청"에서도 유효합니다. 자원이 아직 준비되지 않은 이유가 클라이언트가 서버에 너무 많은 작업을 수행 한 경우에 적합 할 수 있습니다.
Silas S. Brown

8

409 갈등

여러 업데이트의 경우 편집 충돌과 같이 요청 충돌로 인해 요청을 처리 할 수 ​​없음을 나타냅니다. [출처 Wikipedia.]

이것은 적절할 수 있습니다.

데이터를 반환하여 요청을 이행 할 수 없으면 성공하지 못합니다. 202는 서버가 요청을 큐에 넣었고 나중에 요청을 이행 할 것이라고 제안합니다. 그러나 귀하의 경우 현재 데이터 요청이 실패했습니다. 나중에 다시 시도하면 다른 요청입니다.

충돌이 있다고 생각합니다. 데이터를 원하지만 편집 / 업데이트하고 있습니다. Thingy1234가 이미 존재하고 이전에 성공적으로 다운로드되었지만 지금은 편집중인 프로세스를 사용할 수 없었지만 편집이 진행중인 경우에도 마찬가지입니다.


2
왜 이것이 투표에 실패했는지 확실하지 않습니다. 나에게 정답 인 것 같습니다. RFC에서 : "409 (충돌) 상태 코드는 대상 자원의 현재 상태와 충돌하여 요청을 완료 할 수 없음을 나타냅니다.이 코드는 사용자가 충돌을 해결할 수있는 상황에서 사용됩니다. " 요청을 다시 제출하십시오. "서버가 해당 자원을 업데이트하는 중이므로 자원의 현재 상태로 인해 서버가 리턴 할 수없는 자원을 요청했습니다. 고객은 대기 후 다시 제출하여이 문제를 해결할 수 있습니다
Adam

1
@Adam "사용자가 충돌을 해결할 수있을 것"이라는 의미는 재전송에 관한 내용이 기다리는 것 외에 다를 수 있다는 것입니다.
전체적 개발자

3

501-구현되지 않음

정확히 어떻게 들리는 지. 아직 구현되지 않았지만 향후 가용성을 암시하는 기능입니다.

다음은 5xx 오류 요약에 대한 링크 입니다.


4
이 질문에 대해서는 기능 자체가 존재하지만 요청되는 항목이 존재하지 않는 것 같습니다.
Luke

내 대답의 링크에서 @Luke 501의 설명은 '... 요청을 이행 할 수있는 능력이 부족합니다. 일반적으로 이것은 향후 가용성을 의미합니다. ' 이것은 OP가 요구 한 것을 정확하게 충족시킵니다. 그의 서버 또는 DB에 데이터가 있는지 여부에 관계없이. 궁극적 인 결과는 현재 API를 통해 액세스 할 수 없다는 것입니다. 따라서 API는 요청을 이행 할 수 없지만 나중에 http 코드를 통해 사용할 수 있음을 암시하고자합니다.
Dan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.