유효성 검사 실패 또는 잘못된 중복에 대한 REST HTTP 상태 코드


825

REST 기반 API로 응용 프로그램을 작성 중이며 각 요청에 대해 상태 코드를 지정하는 시점에 도달했습니다.

유효성 검사에 실패하거나 요청이 데이터베이스에서 복제본을 추가하려고하는 경우 어떤 상태 코드를 보내야합니까?

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html을 살펴 보았지만 어느 것도 옳지 않은 것 같습니다.

상태 코드를 보낼 때 일반적인 관행이 있습니까?



14
httpstatus.es 열기 , 오른쪽 클릭 >> Pin Tab : P
Salman von Abbas

답변:


779

입력 검증 실패의 경우 : 400 잘못된 요청 + 선택적 설명. 이것은 " RESTful Web Services " 책에서 제안됩니다 . 이중 제출 : 409 충돌


2014 년 6 월 업데이트

관련 사양 은 RFC2616 으로 400 (Bad Request)을 다소 좁게 사용했습니다.

잘못된 구문으로 인해 서버에서 요청을 이해할 수 없습니다.

따라서 의미 상 오류에 부적합하다고 주장 되었을 수도 있습니다. 그러나 더 이상은 아닙니다. 2014 년 6 월 이후 이전 RFC2616을 대체 하는 관련 표준 RFC 7231 은 다음과 같이 400 (잘못된 요청)을 보다 광범위하게 사용합니다.

클라이언트 오류로 인식 된 것으로 인해 서버가 요청을 처리 할 수 ​​없거나 처리하지 않습니다.


3
예, 요청 본문은 구문의 일부입니다.
deamon

62
잘못된 요청은 분명히 이런 종류의 문제에 대한 가장 일반적인 응답입니다. 다른 대안은 422 처리 할 수없는 엔터티입니다. 실제로 WebDav에서 제공되지만 IANA에 등록 된 모든 상태 코드를 재사용하는 것은 완벽하게 유효합니다.
대럴 밀러

19
그렇다면 서버가 파싱 할 수없는 잘못된 데이터와 유효성 검사 오류를 어떻게 구별 할 수 있습니까? 클라이언트는이 두 가지 응답을 완전히 다르게 처리합니다. 유효성 검사를 위해 사용자에게 오류를 표시했을 수 있습니다. 실제로 "잘못된 데이터"의 경우 오류를 기록하므로 요청을 생성하는 메소드의 버그가 수정 될 수 있습니다.
Josh Noe

18
RFC7231에 대한 귀하의 해석에 동의하지 않지만 something perceived to be a client error,이 단락에 제공된 모든 예는 논리적 오류가 아닌 HTTP 프로토콜 위반입니다 (구문, 프레이밍, 라우팅). 따라서 HTTP 사양 응용 프로그램 수준에서 실패한 유효성 검사에 400을 허용 하지 않는다고 생각합니다 .
Dima Tisnek

2
422-처리 불가능한 엔티티를 사용하지 않는 이유는 무엇입니까? 내게 더 논리적 인 것 같습니다
java_geek

278
  • 실패한 유효성 검사 : 403 금지됨 ( "서버가 요청을 이해했지만 요청을 거부하고 있습니다"). 대중의 의견과 달리 RFC2616은 "403은 인증 실패만을위한 것"이라고 말하지 않지만 "403 : 원하는 것을 알고 있지만 그렇게하지는 않습니다"라고 말합니다. 이 상태는 인증 때문일 수도 있고 아닐 수도 있습니다.
  • 복제본 추가 시도 중 : 409 충돌 ( "자원의 현재 상태와 충돌하여 요청을 완료 할 수 없습니다.")

응답 헤더 및 / 또는 본문에 더 자세한 설명을 제공해야합니다 (예 : 사용자 정의 헤더- X-Status-Reason: Validation failed).


17
@deamon : 사양 이 아닙니다 . 즉 Wikipedia입니다. 즉 "HTTP 상태 코드의 의미"에 대한 누군가의 의견; 본질적으로 페이지는 "이것은 Apache가 403으로 의미하는 것, IIS가 403으로 의미하는 것"이라고 말하며 공식 RFC를 참조하는 곳은 없습니다. "403은 Apache가 말한 것을 의미합니다"를 반복하는 것 같습니다. 아니. 실제 RFC 여기에있다 (관련 문서가 아니라 아파치의 구현이 아닌 구현이 아니라 다른 사람의 구현 'IIS) : w3.org/Protocols/rfc2616/rfc2616-sec10.html
Piskvor 건물 왼쪽

57
"10.4.4 403 금지됨 서버가 요청을 이해했지만 요청을 이행하지 않습니다. 승인이 도움이되지 않고 요청을 반복해서는 안됩니다. 요청 방법이 HEAD가 아니고 서버가 요청을하지 않은 이유를 공개하려는 경우 서버가이 정보를 클라이언트에 제공하지 않으려면 상태 코드 404 (찾을 수 없음)를 대신 사용할 수 있습니다. " 강조 할 사항이 없습니다 ( "SHOULD / SHOULD NOT"은 강조가 아닌 RFC 2119 키워드입니다). 이것이 바로 RFC가 아니라 "금지 된"의 의미입니다.
Piskvor

10
나는이 대답을 좋아하지만 여전히 작은 문제가 하나 있습니다. 사양 에 따르면 , 403 이 반환되면 "요청을 반복해서는 안됩니다". 그러나 409를 리턴하면 "사용자가 충돌을 해결하고 요청을 다시 제출할 수있는 상황에서만 허용됩니다". 중복의 경우 충돌을 실제로 해결할 수 없기 때문에 403 이 더 적합 하다고 생각 합니다 (이전 리소스 인스턴스를 삭제하는 경우 제외).
pablobm

2
오류 메시지 자체에 대해서는 이유 문구를 수정해야하므로 헤더를 보내는 HTTP/1.0 403 Form validation errors것이 가장 깨끗한 방법입니다.
aleemb

6
IMO, 422 "처리 할 수없는 엔티티"가 훨씬 더 의미가 있습니다. 내 추론은 서버 가 요청을 이행 하는 것을 거부 하는 것이 아니라 서버 요청을 이행 할 수 없기 때문입니다.
tybro0103

225

상태 코드 422, "처리 할 수없는 엔티티"를 권장 합니다 .

11.2. 422 처리 불가능한 개체

422 (처리 할 수없는 엔티티) 상태 코드는 서버가 요청 엔티티의 컨텐츠 유형을 이해하므로 (415 (지원되지 않는 매체 유형) 상태 코드가 부적절 함) 요청 엔티티의 구문이 정확함 (따라서 400 (잘못된 요청) ) 상태 코드는 부적절하지만 포함 된 지침을 처리 할 수 ​​없습니다. 예를 들어, XML 요청 본문에 올바른 형식 (구문 적으로 올바른)이지만 의미 상 잘못된 XML 명령어가 포함 된 경우이 오류 조건이 발생할 수 있습니다.


11
물론 HTTP 상태 코드입니다 ( iana.org/assignments/http-status-codes 참조) . RFC 2616에 정의 된 것보다 많은 상태 코드가 있습니다.
Julian Reschke

7
WebDAV는 HTTP 확장 입니다. "WebDAV (Web Distributed Authoring and Versioning) 용 HTTP 확장"따라서 상태 코드 422는 http 상태 코드가 아니라 http extions의 상태 코드입니다.
deamon

16
데몬, 그건 말이 안 돼 HTTP는 새로운 코드를 정의하는 방법을 정의하며 WebDAV가하는 일입니다. 이유로 상태 코드 레지스트리가 있습니다.
Julian Reschke

14
FYI-422의 RFC 설명 : 11.2. 422 처리 할 수없는 엔티티 422 (처리 할 수없는 엔티티) 상태 코드는 서버가 요청 엔티티의 컨텐츠 유형을 이해함을 의미하므로 (415 (지원되지 않는 매체 유형) 상태 코드가 부적절 함) 요청 엔티티의 구문이 정확합니다 (따라서 400 (잘못된 요청) 상태 코드는 부적절하지만 포함 된 지침을 처리 할 수 ​​없습니다. 예를 들어, XML 요청 본문에 올바른 형식 (구문 적으로 올바른)이지만 의미 상 잘못된 XML 명령어가 포함 된 경우이 오류 조건이 발생할 수 있습니다.
Steve Kallestad

6
그리고 스레드는 '만료'되지 않습니다. 생활 상태를 유지해야하거나 최고의 Google 검색 결과가 정확하지 않게됩니다.
James Billingham

81

200,300, 400, 500은 모두 매우 일반적입니다. 일반을 원하면 400이 정상입니다.

422는 점점 더 많은 수의 API에서 사용되며 Rails에서도 즉시 사용됩니다.

API에 대해 어떤 상태 코드를 선택 하든지간에 누군가 동의하지 않을 것입니다. 그러나 '400 + text status'가 너무 일반적이라고 생각하기 때문에 422를 선호합니다. 또한 JSON 준비 파서를 사용하지 않습니다. 반대로 JSON 응답이있는 422는 매우 명시 적이며 많은 오류 정보가 전달 될 수 있습니다.

JSON 응답에 대해 말하자면,이 경우 Rails 오류 응답을 표준화하는 경향이 있습니다.

{
    "errors" :
    { 
        "arg1" : ["error msg 1", "error msg 2", ...]
        "arg2" : ["error msg 1", "error msg 2", ...]
    }
}

이 형식은 양식 유효성 검사에 적합하며, '오류보고 풍부 성'측면에서 가장 복잡한 경우를 고려합니다. 오류 구조가이 경우 모든 오류보고 요구를 처리 할 수 ​​있습니다.


2
인수 간의 상호 작용으로 인해 발생하는 오류는 어떻습니까? 즉, arg1유효하고 arg2유효하지만 전송 된 특정 값과 함께이 둘의 조합은 유효하지 않습니다.
요나

1
나는 그렇게 생각하지 않을 것이다. 관계를 소유 한 것으로 보이는 것을 선택하십시오.
sethcall

또는 두 인수 모두에서 오류가 발생했습니다. 사용자로서 충돌하는 각 필드의 오류를보고 싶다고 생각합니다.
snuggles

좋은!. 명시 적으로 더 나은 암시보다
bhathiya - 페레라

46

200

Uh ... (309, 400, 403, 409, 415, 422) ... 성공적인 HTTP 요청 이지만 실패한 REST 호출에 대한 최상의 리턴 코드가 무엇인지 추측, 논쟁 및 표준화하려는 많은 답변이 있습니다.

HTTP 상태 코드와 REST 상태 코드를 혼합하는 것은 잘못 입니다.

그러나 많은 구현이 혼합되어있는 것을 보았으며 많은 개발자가 저에게 동의하지 않을 수 있습니다.

HTTP 리턴 코드는 HTTP Request자체 와 관련이 있습니다. REST 호출은 하이퍼 텍스트 전송 프로토콜 요청을 사용하여 수행되며 호출 된 REST 메소드 자체보다 낮은 레벨에서 작동합니다. REST는 개념 / 접근 방식이며 결과 는 비즈니스 / 논리적 결과이며 HTTP 결과 코드는 전송 코드입니다 .

예를 들어, / users /를 호출 할 때 "404를 찾을 수 없음"을 반환하면 혼동 될 수 있습니다.

  • URI가 잘못되었습니다 (HTTP)
  • 사용자를 찾을 수 없습니다 (REST)

"403 금지 / 액세스 거부"는 다음을 의미 할 수 있습니다.

  • 특별 허가가 필요합니다. 브라우저는 사용자 / 암호를 요청하여이를 처리 할 수 ​​있습니다. (HTTP)
  • 서버에 잘못된 액세스 권한이 구성되었습니다. (HTTP)
  • 인증이 필요합니다 (REST)

그리고 목록은 '500 서버 오류'(Apache / Nginx HTTP 발생 오류 또는 REST의 비즈니스 제한 오류) 또는 기타 HTTP 오류 등으로 계속 될 수 있습니다.

코드에서 실패 이유, HTTP (전송) 실패 또는 REST (논리) 실패를 이해하기는 어렵습니다.

HTTP 요청이 실제로 성공적으로 수행 된 경우 레코드의 발견 여부에 관계없이 항상 200 코드를 리턴 해야합니다 . URI 자원이 발견 되어 HTTP 서버에 의해 처리 되었기 때문 입니다. 예, 빈 세트를 반환 할 수 있습니다. HTTP 결과로 200을 가진 빈 웹 페이지를 수신 할 수 있습니까?

이 대신 몇 가지 옵션으로 200 HTTP 코드를 반환 할 수 있습니다.

  • 무언가 잘못되면 JSON 결과의 "오류"객체
  • 레코드를 찾지 못하면 빈 JSON 배열 / 객체
  • 보다 나은 처리를 위해 이전 옵션과 결합 된 부울 결과 / 성공 플래그입니다.

또한 일부 인터넷 제공 업체는 귀하의 요청을 가로 채서 404 HTTP 코드를 반환 할 수 있습니다. 이것은 데이터를 찾을 수 없다는 것을 의미하지는 않지만 전송 수준에서 문제가 있습니다.

에서 위키 :

2004 년 7 월 영국의 통신 제공 업체 인 BT Group은 Cleanfeed 콘텐츠 차단 시스템을 구축했습니다.이 콘텐츠 차단은 Internet Watch Foundation에서 불법으로 식별 한 콘텐츠에 대한 요청에 404 오류를 반환합니다. 다른 ISP는 같은 상황에서 HTTP 403 "금지"오류를 반환합니다. 검열을 은폐하기위한 수단으로 가짜 404 오류를 사용하는 관행도 태국과 튀니지에서보고되었습니다. 2011 년 혁명 이전에 검열이 심했던 튀니지에서 사람들은 가짜 404 오류의 본질을 알게되고 "보이지 않는 검열"을 나타내는 "Ammar 404"라는 가상의 캐릭터를 만들었습니다.

왜 이런 식으로 대답하지 않습니까?

{
  "result": false,
  "error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}

요청이 논리적으로 실패하더라도 Google은 항상 지오 코딩 API에서 상태 코드로 200을 반환합니다. https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

REST 요청이 실패하더라도 Facebook은 HTTP 요청 성공에 대해 항상 200을 반환합니다. https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling

간단한 HTTP 상태 코드는 HTTP 요청을위한 것입니다. REST API는 Your이고 상태 코드를 정의하십시오.


3
실제로 REST에 HTTP 상태 코드를 사용하면 훨씬 더 혼란 스럽습니다 .1) 개발자 도구 상자에 4xx가 표시되고 서버가 합리적인 가치를 반환했는지 또는 요청을 전혀 처리하지 못했는지 여부를 확인하여 말할 수는 없습니다. 그리고 2) 모든 오류 / 예외 / 캐치 처리기는 응답으로 반환 된 서버를 확인해야합니다 (대부분 서비스 호출마다 서버를 수행해야하기 때문에 필요하지 않습니다) 3) 동일한 페이로드 ( 복잡하고 중복 된 코드로 이어지는 성공과 오류 경로 모두에서 유형) ... 매우 혼란 스럽습니다.
szczepanpp

9
이 답변은 HTTP 프로토콜의 원래 의미론과 아키텍처 스타일 로서 REST over HTTP가 HTTP를 재사용하여 웹 서비스 API를 구현 하는 방법을 혼동합니다 . 아키텍처 스타일 인 REST는 엄격하게 준수해야 할 표준이 아니며 제안 된 접근 방식입니다. 유효성 검사 실패에 200 응답을 사용하는 것은 옳고 그름은 아니지만 고객이 요청이 성공했다고 응답하는 것은 혼란 스럽지만 실제로는 응답 본문 내에서 모호한 중요한 세부 사항 인 유효성 검사 실패로 인해 실패했습니다. 클라이언트가 이해하기 위해 구문 분석해야하는 의미론.
Kevin Hooke

5
@Marcodor API 호출이 실패하지만 성공을 나타내는 200을 반환하면 어떻게 좋은 생각입니까? API 소비자에게는 불분명하고 혼동됩니다.
Kevin Hooke

3
HTTP와 REST 오류의 분리 만이 아니라 여러 가지 이유로 정정하십시오. REST 유효성 검사에는 종종 더 많은 뉘앙스가 필요합니다. 예를 들어, 레코드가 승인되었지만 고유 인덱스 위반에 대해 중복 대 거부로 플래그가 지정되었습니다. 또한 일관된 수익 모델을 원합니다. .NET BadRequest()메소드에는 일반 리턴 모델과 다른 고유 한 리턴 모델이 있습니다. 파싱하는 것은 악몽이다. @KevinHooke, REST 유효성 검사 오류로 HTTP 200을 반환하는 것은 "메시지를 받았는데 답이 없습니다. 그 이유는 다음과 같습니다."라고 말하는 것과 같습니다. HTTP 400을 반환하면 "내가 무슨 말을하는지 모르겠다"고 말합니다.
Neil Laslett

5
"구글이 그것을하기 때문에, 옳 아야한다"라는 주장은 미쳤다. 구글이 아이들을 구현 한 것에 도전하는 것은 괜찮다. 실패한 휴식 호출에 대해 HTTP 200을 반환하면 API 호출자가 4xx이어야하며 본문에 예쁜 JSON / XML을 포함 할 수 있습니다 ... 광기를 함께 막을 수 있습니다.
Jeryl Cook

43

데이터베이스의 사본은이어야합니다 409 CONFLICT.

422 UNPROCESSABLE ENTITY유효성 검사 오류에 사용 하는 것이 좋습니다 .

여기 에 4xx 코드에 대한 자세한 설명이 나와 있습니다 .


6

상태 코드 304 Not Modified 는 중복 요청에 대해 수용 가능한 응답을합니다. 이것은 If-None-Match엔티티 태그 를 사용하는 헤더를 처리하는 것과 유사합니다 .

내 의견으로는 @Piskvor의 대답은 원래 질문의 의도라고 생각하는 것보다 더 분명한 선택이지만 관련있는 대안이 있습니다.

중복 요청을 오류가 아닌 경고 또는 알림으로 처리하려는 경우 응답 상태 코드가 304수정되지 않음 및 Content-Location기존 자원을 식별하는 헤더가 유효합니다. 의도가 단순히 자원이 존재하도록하는 것이라면 중복 요청은 오류가 아니라 확인입니다. 요청이 잘못되지 않았지만 단순히 중복되어 클라이언트가 기존 리소스를 참조 할 수 있습니다.

즉, 요청은 양호하지만 자원이 이미 존재하므로 서버는 추가 처리를 수행 할 필요가 없습니다.


6
304는 캐싱을 지원하기 위해 GET 작업을위한 것임을 이해했습니다.
Sinaesthetic

6

Ember-Data의 ActiveRecord 어댑터는 422 UNPROCESSABLE ENTITY서버에서 리턴 될 것으로 예상 합니다. 따라서 클라이언트가 Ember.js로 작성된 경우 422를 사용해야합니다. 그런 다음 DS.Errors는 반환 된 오류로 채워집니다. 물론 422를 어댑터의 다른 코드변경할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.