매개 변수가 구문 적으로 정확하지만 비즈니스 규칙을 위반하는 경우 HTTP 400 (잘못된 요청) 상태를 리턴해야합니까?


56

정수를 매개 변수로 사용하는 REST 끝 점이 있다고 가정 해보십시오.

/makeWaffles?numberOfWaffles=3

이 경우 음수의 와플을 만들 수 없으므로 숫자가 양수가되기를 원합니다 (0 와플을 요청하는 것은 시간 낭비입니다). 따라서 양의 정수를 포함하지 않는 요청을 거부하고 싶습니다. 또한 최대 정수를 초과하는 요청을 거부하고 싶습니다 (MAX_INTEGER라고 가정 해 봅시다).

누군가 양수가 아닌 와플을 요청하는 경우 HTTP 400 (잘못된 요청) 상태를 반환해야합니까? 내 초기 생각은 그렇습니다. 요청을 완료하는 데 유효한 숫자가 아닙니다. 그러나 RFC 는 비즈니스 규칙을 던지는 이유로 언급하지 않습니다.

400 (잘못된 요청) 상태 코드는 클라이언트 오류 (예 : 잘못된 요청 구문, 잘못된 요청 메시지 프레이밍 또는기만적인 요청 라우팅)로 인식되어 서버가 요청을 처리 할 수 ​​없거나 처리하지 않음을 나타냅니다.

비즈니스 규칙은 이러한 세 가지 예에 해당되지 않습니다. 문법적으로 정확하고 제대로 구성되어 있으며기만적인 요청 라우팅이 아닙니다.

매개 변수가 구문 적으로 정확하지만 비즈니스 규칙을 위반하는 경우 HTTP 400 (잘못된 요청) 상태를 반환해야합니까? 아니면 더 적절한 상태로 돌아갈 수 있습니까?



답변:


38

이것은 훌륭한 질문이며 HTTP 리턴 코드의 역사적 맥락 (그리고 모순되는 정의)을 고려할 때 여전히 관련성이 높습니다. 이 질문에 대한 답 중에서도 상충되는 정의가 있습니다. 이것은 연대순으로 움직여 명확하게 할 수 있습니다.

RFC 2616 (1999 년 6 월)

10.4.1 400 잘못된 요청

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

이 RFC 기준으로이 상태 코드는 구문 상 유효하지 않은 요청에만 적용되었습니다. 시맨틱 검증을위한 상태 코드에 차이가있었습니다. 따라서 RFC 4918이 등장했을 때 새로운 코드가 탄생했습니다.

RFC 4918 (2007 년 6 월)

11.2. 422 처리 불가능한 개체

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

422 처리 할 수없는 엔티티가 4xx 상태 코드의 원래 스펙에서 시맨틱 유효성 검증 간격을 채우기 위해 작성되었습니다. 그러나 2014 년에 또 다른 관련 RFC가 등장하여 400은 더 이상 구문에 국한되지 않습니다 .

RFC 7231 (2014 년 6 월, RFC 2616을 명시 적으로 사용하지 않음)

6.5.1. 400 잘못된 요청

400 (잘못된 요청) 상태 코드는 클라이언트 오류 (예 : 잘못된 요청 구문, 잘못된 요청 메시지 프레이밍 또는기만적인 요청 라우팅)로 인식되어 서버가 요청을 처리 할 수 ​​없거나 처리하지 않음을 나타냅니다.

422 설명에 따르면 400이 부적절한 이유는 잘못된 요청 구문에 대해서만 400 (RFC 2616 기준)을 반환해야하기 때문입니다. 그러나 RFC 7231부터 엄격한 구문 오류 정의는 더 이상 400에 적용되지 않습니다 .

당면한 질문으로 돌아 가기 :이 문맥에서 422는 기술적으로 더 구체적이지만, API 매개 변수의 의미 론적 검증에 400 또는 422가 사용되는 것을 볼 수 있습니다. 422의 정의가 현재 시점에서 기술적으로 오래 되었기 때문에 내 API에서 422를 사용하는 것이 주저합니다 (공식적으로 어디서나 공식적으로 인정되는지는 알 수 없지만). 422의 사용을 장려하는 Fran의 답변에서 언급 된 기사는 RFC 7231이 HTTP 400을 명확하게하기 2 년 전에 2012 년에 작성되었습니다. 둘 중 하나만 표준화하십시오.


42

적어도 첫 번째 답변을 읽었을 때 잘못된 요청 (400)은 "기본적으로 잘못 되었기 때문에 귀하의 요청을 처리 할 수도 없습니다."라는 의미이므로 첫 번째 답변을 읽었으며 이에 동의하지 않았습니다. 그리고 나는 422를 반환하는 경우를 만드는 이 게시물 을 발견했습니다 .

IETF에서

422 처리 할 수없는 엔터티 (WebDAV; RFC 4918) 요청이 제대로 구성되었지만 의미 오류로 인해 따라갈 수 없습니다.

요청이 잘 구성되어 있기 때문에 더 적절한 응답처럼 보이지만 유효성 검사 규칙을 통과하지는 않습니다.


5
"400은 잘못된 구문을, 422는 잘못된 의미를 의미합니다."라고 설명했습니다.
cbojar

33
모든 x00 코드는 "모두 잡기"일반 코드입니다. 400은 부적절 하지 않고 덜 구체적 입니다.
Jack

1
좋은 답변이지만 @GoFree가 제공하는 답변은 더 의미가 있습니다.
Ewerton

2
모든 사람이 알고있는 코드를 반환하는 경우가 실제로 있습니다. 당연히 모든 사람이 422를 찾아야 할 것이며, 나는 여전히 무엇을 만들어야할지 알지 못할 것입니다.
sylvanaar

8

예, 엔드 포인트의 암시 적 계약을 따르지 않는 입력은 "클라이언트 오류로 인식 된 것"이며 400을 반환해야합니다.

이에 대한 예외는 비즈니스 규칙이 보안과 관련된 경우 ( 401 Unauthorized또는 403 Forbidden더 나은 경우)입니다. 또는 400을 보내면 무언가 존재에 대한 정보가 유출되고 a 404 Not Found가 더 적합 할 수 있습니다.


8

아닙니다. HTTP 코드는 응용 프로그램의 HTTP 계층을위한 것입니다. 비즈니스 규칙은 완전히 다른 계층이며 응용 프로그램에 따라 다르므로 "프로토콜"을 만들어야합니다.

묵시가 발생하고 HTTP 프로토콜에서 비둘기 사용으로 전환해야한다고 상상해보십시오. 비둘기는 리턴 코드가 없으므로이를 수용하기 위해 비즈니스 계층을 변경해야합니다. 그러나 비즈니스는 실제로 어떤 식 으로든 변경되지 않았으므로 비즈니스 계층을 변경할 필요가 없습니다. 이 두 계층 (교통 및 비즈니스) 간의 긴밀한 연결을 보여줍니다.

질문으로 돌아 가기 : 요청으로 발생한 내용을 설명하는 본문과 함께 "200 OK"를 반환해야합니다. 사양은 분명히 다음과 같이 말합니다.

https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1 .

200 OK

요청이 성공했습니다. 응답과 함께 반환 되는 정보는 요청에 사용 된 방법에 따라 다릅니다 ( 예 :

조치 결과를 설명하거나 포함하는 엔티티를 POST 합니다.

HTTP 요청이 성공 했습니까? 예, 웹 서버는 해당 요청으로 수행 할 작업을 알고 있습니다 (예 : 응용 프로그램의 서버 부분으로 전달). 그런 다음 웹 서버는이 요청을 응용 프로그램의 서버 부분으로 전달합니다.이 부분은 POST 된 데이터를 가져 와서 처리하고 (귀하의 경우 유효성 검사) 응용 프로그램의 클라이언트 부분에 정상적인 응답 (HTTP 응답 본문)을 반환합니다 . 응용 프로그램의 서버 부분에서 보낸이 답변은 "좋아요, 보낸 데이터가 유효합니다"또는 "죄송합니다. 보낸 데이터가 유효하지 않습니다"일 수 있습니다. 그리고 답변의 의미를 이해하는 것은 응용 프로그램의 클라이언트 부분에 달려 있습니다.

PS : "400 잘못된 요청" 은 웹 서버가 원하는 것을 이해하지 못했음 을 의미합니다. 애플리케이션의 서버 부분이 요청을 수신하지 않았 음을 의미합니다. 또는 적어도 그것이 의미하는 바입니다 :-)

편집 : 방금 POST가 아니라 GET 요청을하고 있음을 깨달았습니다. GET이 응용 프로그램의 상태를 변경해서는 안되기 때문에 이것은 나쁜 생각입니다. GET은 단순히 서버에서 데이터를 검색해야합니다. 그러나 귀하의 요청에 따라 실제로 응용 프로그램의 상태를 변경하고 있으므로 실제로 POST를 사용해야합니다.


1
예,이 경우 404를 반환하는 것이 좋습니다. 서버가 항상 본문에 설명과 함께 200 OK를 보내야한다는 말은 아닙니다.
GoFree

내가 지금까지 본 더 나은 설명. 나는 같은 질문을 가지고 있으며 모든 단어가 나와 다르게 생각하고 당신은 @GoFree
Ewerton

@GoFree API 디자인을 다시 생각하면 좋은 답변입니다. 그러나 REST API를 사용할 때 HTTP와 응답 코드를 비즈니스 규칙 계층의 주요 부분으로 사용하는 것이 사실입니까?
토마스 로리아

1
@Thomas Lauria 아직 RESTFUL API의 적절한 구현을 보지 못했습니다. 그러나 REST API는 오늘날 유행어이므로 모든 회사는 실제로 그 개념을 이해하지 않고 그것을 사용해야합니다 (기술이 아닌 단어). 예, 어디에서나 잘못된 방식으로 사용되고 있습니다. 프로그래머가 일반적으로 작성하는 것은 REST API가 아니라 HTTP API 또는 API OVER HTTP입니다. 실제로 몇 가지 훌륭한 RESTFUL 구현 중 하나는 HTTP 자체입니다. :)
GoFree

1
입력 값이 너무 높거나 너무 낮거나 없음, 제품 재고 부족 등의 비즈니스 수준 오류를 설명하기 위해 응용 프로그램이 응답 본문에 "오류"필드를 포함하는 경우 200-OK를 사용하는 것이 특히 논리적입니다.
Roland

-3

모두 동의 할 지 모르지만 409-Conflict를 사용하고 있습니다. 409가 시스템 상태와 충돌하는 경우가 많지만 요청자에 의해 허용 된 범위를 벗어난 데이터 값의 충돌을 해결할 수 있고 409를 수용 할 수 있다는 해석을 받아 들였습니다. 422 요청이 합리적이라고 생각합니다 올바르게 구성되었지만 요청한대로 처리 할 수 ​​없습니다. 그러나 많은 답변을 구현하지 않으려면 400을주는 것이 여전히 허용됩니다.


5
409는 "이 상태를 넣으려는 상태가 다른 클라이언트가이를 넣는 상태와 충돌합니다"를 의미합니다. 동시 쓰기를 차단하기위한 것입니다 (예 : ETag 사용)
Jack
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.