Programing

잘못된 요청 구문이 아닌 논리적 오류에 대한 HTTP 400 (잘못된 요청)

lottogame 2020. 11. 25. 07:30
반응형

잘못된 요청 구문이 아닌 논리적 오류에 대한 HTTP 400 (잘못된 요청)


HTTP / 1.1 사양 (2616 RFC는) 의 의미에 대해 말하기를 다음이 상태 코드 400 잘못된 요청 (§10.4.1을) :

잘못된 구문으로 인해 서버에서 요청을 이해할 수 없습니다. 클라이언트는 수정없이 요청을 반복해서는 안됩니다.

요즈음 HTTP 기반 API 중 요청시 구문 오류가 아닌 논리적 오류 를 의미하는 데 400을 사용하는 일반적인 관행이있는 것 같습니다 . 내 생각에 API는 400 (클라이언트 유도)과 500 (서버 유도) 을 구분하기 위해이 작업을 수행하고 있습니다. 비 구문 오류를 나타 내기 위해 400을 사용하는 것이 허용되거나 올바르지 않습니까? 허용되는 경우 RFC 2616에 대한 주석이 달린 참조가 400의 의도 된 사용에 대한 더 많은 통찰력을 제공합니까?

예 :


이 시간 현재, 최신 초안 HTTPbis 것입니다 사양은, 대체 및 RFC 2616 무용지물로 만들려면 상태 :

400 (잘못된 요청) 상태 코드는 수신 된 구문이 유효하지 않거나 무의미하거나 서버가 처리하려는 항목에 대한 일부 제한을 초과하기 때문에 서버가 요청을 처리 할 수 ​​없거나 처리하지 않을 것임을 나타냅니다.

이 정의는 물론 여전히 변경 될 수 있지만 논리적 오류에 400으로 응답하는 널리 사용되는 관행을 비준합니다.


상태 422 ( RFC 4918, 섹션 11.2 )가 오릅니다.

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


HTTPbis는 논리적 오류도 다루도록 400 Bad Request의 구문을 처리합니다. 따라서 400은 422를 통합합니다.

에서 https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-18#section-7.4.1
서버가 또는 예를 들어, 잘못된 (때문에 클라이언트 오류로 요청을 처리하지 않을 수 없다 " 통사론)"


비록 논리적 오류를 나타 내기 위해 400을 사용했지만, 스펙이 읽는 방식 때문에이 경우 400을 반환하는 것은 잘못되었다고 말해야합니다. 내가 그렇게 생각하는 이유는 논리적 오류가 다른 엔티티와의 관계가 실패하거나 만족스럽지 않고 다른 엔티티를 변경하면 나중에 동일한 정확한 결과가 발생할 수 있다는 것입니다. 직원이 존재하지 않을 때 직원을 부서의 구성원으로 추가하려고 (완전히 가설)하는 것과 같습니다 (논리적 오류). 직원이 존재하지 않아 직원을 구성원 요청으로 추가하지 못할 수 있습니다. 그러나 직원이 시스템에 추가 된 후에도 동일한 요청이 전달 될 수 있습니다.

내 2 센트 만 ... 요즘 RFC에서 언어를 해석 할 변호사와 판사가 필요합니다. :)

고마워, 비쉬


HTTP 수준 (요청 줄, 헤더 등)의 실제 요청이 구문 상 유효하더라도 요청에 잘못된 데이터 있는 것은 구문 오류 라고 주장 할 수 있습니다 .

예를 들어 Restful 웹 서비스가 사용자 지정 XML 콘텐츠 유형이 application/vnd.example.com.widget+xmlPOST를 수락하는 것으로 문서화되고 대신 의미없는 일반 텍스트 또는 이진 파일을 보내는 경우이를 구문 오류로 처리하는 것이 합리적입니다. 요청 본문은 그렇지 않습니다. 예상 된 형태로.

나는 이것을 뒷받침하는 공식적인 언급을 알지 못합니다. 평소처럼 RFC 2616을 해석하는 것 같습니다.

업데이트 : RFC 7231 §6.5.1 에서 수정 된 문구를 참고하십시오 .

400 (Bad Request) 상태 코드는 잘못된 요청 구문, 잘못된 요청 메시지 프레이밍 또는 사기성 요청 라우팅과 같이 클라이언트 오류로 인식되는 문제로 인해 서버가 요청을 처리 할 수 ​​없거나 처리하지 않을 것임을 나타냅니다.

이 주장을 지금은 쓸모없는 RFC 2616 §10.4.1 보다 더 많이 지원하는 것 같습니다 .

잘못된 구문으로 인해 서버에서 요청을 이해할 수 없습니다. 클라이언트는 수정없이 요청을 반복해서는 안됩니다.


Java EE 서버에서 URL이 존재하지 않는 "웹 응용 프로그램"을 참조하면 400이 반환됩니다. "구문 오류"입니까? 구문 오류가 의미하는 바에 따라 다릅니다. 나는 그렇다고 말할 것입니다.

영어 구문 규칙은 품사 간의 특정 관계를 규정합니다. 예를 들어 "Bob marries Mary"는 {명사 + 동사 + 명사} 패턴을 따르기 때문에 구문 상 정확합니다. "Bob married Mary"는 구문 상 부정확 한 반면 {명사 + 명사 + 명사}.

단순 URL의 구문은 {프로토콜 + : + // + 서버 + : + 포트}입니다. 이 " http://www.google.com:80 " 에 따르면 구문 상 정확합니다.

하지만 "abc : //www.google.com : 80"은 어떻습니까? 똑같은 패턴을 따르는 것 같습니다. 그러나 실제로는 구문 오류입니다. 왜? 'abc'는 DEFINED 프로토콜이 아니기 때문입니다.

요점은 우리가 400 상황인지 여부를 결정하려면 문자와 공백 및 구분 기호를 구문 분석하는 것 이상이 필요하다는 것입니다. 또한 유효한 "품사"를 인식해야합니다.


이건 어려워.

우리는 그래야만 해;

  1. 클라이언트가 요청, 헤더 또는 본문을 변경할 권한이있는 경우에만 4xx 오류를 반환합니다. 그러면 요청이 동일한 의도로 성공하게됩니다.

  2. 예상되는 돌연변이가 발생하지 않았을 때 오류 범위 코드를 반환합니다. 즉, DELETE가 발생하지 않았거나 PUT가 아무것도 변경하지 않았습니다. 그러나 POST는 사양이 새 위치에서 리소스를 생성하거나 페이로드를 처리하는 데 사용해야한다고 명시하기 때문에 더 흥미 롭습니다.

Vish의 답변에있는 예를 사용하여 요청이 직원 Priya를 마케팅 부서에 추가하려고했지만 Priya를 찾을 수 없거나 계정이 보관 된 경우 이는 애플리케이션 오류입니다.

요청이 제대로 작동하고 애플리케이션 규칙에 도달했으며 클라이언트가 모든 것을 올바르게 수행했으며 ETag가 일치했습니다.

HTTP를 사용하고 있기 때문에 리소스 상태에 대한 요청의 영향에 따라 응답해야합니다. 그리고 그것은 API 디자인에 달려 있습니다.

아마도 당신이 이것을 설계했을 것입니다.

PUT { updated members list } /marketing/members

성공 코드를 반환하면 리소스의 "교체"가 작동했음을 나타냅니다. 리소스에 대한 GET은 변경 사항을 반영하지만 그렇지 않습니다.

따라서 이제 적절한 네거티브 HTTP 코드를 선택해야합니다. 코드는 애플리케이션이 아닌 HTTP 프로토콜을위한 것이기 때문에 까다로운 부분입니다.

공식 HTTP 코드를 읽으면이 두 가지가 적합 해 보입니다.

409 (충돌) 상태 코드는 대상 리소스의 현재 상태와 충돌하여 요청을 완료 할 수 없음을 나타냅니다. 이 코드는 사용자가 충돌을 해결하고 요청을 다시 제출할 수있는 상황에서 사용됩니다. 서버는 사용자가 충돌의 원인을 인식하기에 충분한 정보를 포함하는 페이로드를 생성해야합니다 (SHOULD).

500 (내부 서버 오류) 상태 코드는 서버가 요청을 이행하지 못하게하는 예기치 않은 조건이 발생했음을 나타냅니다.

우리는 전통적으로 500을 처리되지 않은 예외처럼 생각했지만 :-/

일관되게 적용되고 설계되는 한 자신의 상태 코드를 발명하는 것이 부당하다고 생각하지 않습니다.

이 디자인은 다루기가 더 쉽습니다.

PUT { membership add command } /accounts/groups/memberships/instructions/1739119

Then you could design your API to always succeed in creating the instruction, it returns 201 Created and a Location header and any problems with the instruction are held within that new resource.

A POST is more like that last PUT to a new location. A POST allows for any kind of server processing of a message, which opens up designs that say something like "The action successfully failed."

Probably you already wrote an API that does this, a website. You POST the payment form and it was successfully rejected because the credit card number was wrong.

With a POST, whether you return 200 or 201 along with your rejection message depends on whether a new resource was created and is available to GET at another location, or not.

With that all said, I'd be inclined to design APIs that need fewer PUTs, perhaps just updating data fields, and actions and stuff that invokes rules and processing or just have a higher chance of expected failures, can be designed to POST an instruction form.

참고URL : https://stackoverflow.com/questions/4781187/http-400-bad-request-for-logical-error-not-malformed-request-syntax

반응형