서버에서 비즈니스 로직 오류를 나타내는 데 HTTP 상태 코드를 사용해야합니까?


20

나는 클라이언트 (브라우저의 JS)가 서버와 대화하기위한 API 디자인을 약간 교차하고 있습니다. 안전 잠금으로 인해 조치 실패를 표시하기 위해 HTTP 409 충돌을 사용합니다. 안전 잠금 장치는 개발자가 실수로 고객의 생산 시스템을 변경하지 못하게합니다. 나는 특정 API 호출이 실패한 이유를 나타 내기 위해 클라이언트에서 409를 조금 더 우아하게 처리하는 임무를 맡았습니다.

내 솔루션은 409로 인해 오류가 발생했을 때 클라이언트에 알림을 표시하는 AJAX 호출의 실패 처리기를 래핑하는 것입니다. 모두 괜찮으며 동일한 메커니즘을 사용하는 다른 4XX 및 5XX 오류와 함께 잘 작동합니다.

비즈니스 로직 오류가 발생했을 때 경로 처리기 중 하나가 409로 응답하는 문제가 발생했습니다. AJAX 래퍼는 안전 잠금이 켜져 있다고보고하지만 클라이언트의 기존 오류 처리기는 문제가 본문을 기반으로하는 문제를보고합니다. 응답의. 간단한 해결책은 핸들러의 응답 또는 안전 잠금을 나타내는 데 사용하는 상태 코드를 변경하는 것입니다.

비즈니스 로직 오류를 나타내는 데 HTTP 상태 코드를 사용해야합니까? 이 질문 은 내가 직면 한 것과 같은 문제를 다루지 만 많은 견인력을 얻지 못했습니다. 링크 된 답변에서 제안한 것처럼 비즈니스 논리 내에서 실패를 나타내는 적절한 본문으로 HTTP 200 OK를 사용하려고합니다.

여기에 강한 의견이 있습니까? 누구든지 이것이 실패를 나타내는 잘못된 방법이라는 것을 확신 할 수 있습니까?


3
나는 간단한 의견을 답변으로 올리는 것을 망설 인다. 한마디로 : 일반적으로 비즈니스 오류를 나타내는 데 HTTP 상태 코드를 사용하지 않습니다. 클라이언트와 서버 간의 통신 상태에만 관련되어야합니다. 유효성 검사 또는 비즈니스 논리 오류를 반환하기에 적합한 상태 코드는 다음과 같습니다 400 Bad Request. 이러한 분리의 이유는 미래의 시스템, 개발자 또는 독자가 전 세계 표준의 편차로 인해 혼란 스러울 수 있기 때문입니다.
Ivo Coumans

@IvoCoumans :이 질문에 대답 해주세요. 400 Bad Request담요로 HTTP 코드는 비즈니스 로직 오류를 클래스로 다루는 것이 가장 좋습니다.
9000

개인 취향이지만 400 Bad Request데이터가 없거나 읽거나 파싱 할 수없는 경우 사용하는 경향이 있습니다 . 즉, 요청 데이터 자체가 어떤 식 으로든 나쁩니다.
Kasey Speakman

"비즈니스 로직 오류"의 의미를 확장하십시오. 매우 모호합니다. (올바른) 데이터 유효성 검사에 따라 유효하지 않은 입력, 다른 시점에서는 유효하지만 현재 상태에서는 유효하지 않은 입력 또는 유효한 입력을 거부하는 비즈니스 로직의 버그를 의미합니까?
jpmc26

@ jpmc26 일반적인 질문이므로 의도적으로 모호했습니다. 서버는 요청에 잘 대처했지만 쿼리 / 어설 션이 적합하지 않다고 결정했습니다.
Joe Shanahan

답변:


19

케이시 는 요점을 다룹니다.

모든 웹 API의 핵심 아이디어 : 도메인을 문서 저장소처럼 보이도록 조정하고 있습니다. GET / PUT / POST / DELETE 등은 문서 저장소와 상호 작용하는 모든 방법입니다.

따라서 어떤 코드를 사용해야하는지 생각 하는 방법은 문서 저장소에서 유사한 작업이 무엇인지, 그리고 해당 아날로그에서 이러한 실패가 어떻게 발생하는지 이해하는 것입니다.

2xx는 완전히 부적합하다

2xx (성공) 상태 코드 클래스는 클라이언트 요청이 성공적으로 수신, 이해 및 수락되었음을 나타냅니다.

5xx도 적합하지 않습니다

5xx (서버 오류) 클래스 상태 코드는 서버가 오류를 인식했음을 나타냅니다.

이 경우 서버는 실수하지 않았습니다. 현재 해당 방식으로 해당 리소스를 수정해서는 안된다는 것을 알고 있습니다.

비즈니스 논리 오류 (현재 비즈니스 불변으로 인해 제안 된 편집이 허용되지 않음)는 아마도 409 일 것입니다.

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

마지막 409 응답의 페이로드는 소비자에게 잘못된 문제에 대한 정보를 전달해야하며, 소비자를 갈등 해결에 도움이되는 리소스로 안내하는 하이퍼 미디어 제어를 포함하는 것이 이상적입니다.

내 솔루션은 409로 인해 오류가 발생했을 때 클라이언트에 알림을 표시하는 AJAX 호출의 실패 처리기를 래핑하는 것입니다. 모두 괜찮으며 동일한 메커니즘을 사용하는 다른 4XX 및 5XX 오류와 함께 잘 작동합니다.

나는 이것을 문제라고 지적 할 것이다. 클라이언트에서의 구현은 상태 코드가 문제를 정의하기에 충분하다고 가정했습니다. 대신 클라이언트 코드는 페이로드를 검토하고 사용 가능한 정보에 따라 행동해야합니다.

즉, 문서 저장소가 수행하는 방식

409  Conflict

your proposed change has been declined because ${REASON}.  
The following resolution protocols are available: ${LINKS[@]})

a를 사용한 동일한 접근 방식 400 Bad Request도 허용됩니다. "대략"은 "요청에 문제가있었습니다."로 번역됩니다. 우리는 어떤 상태 코드가 가장 적합한 지 알아낼 필요가 없습니다. 자세한 내용은 페이로드를 참조하십시오. "

422를 사용합니다. 입력이 유효하므로 400은 올바른 오류 코드가 아닙니다.

WebDAV 사양에는 이 권장 사항이 포함되어 있습니다

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

나는 그것이 꽤 일치한다고 생각하지 않습니다 (그러나 400대안으로 의심의 여지가 있음에 동의하지만 ). 내 해석은 422"당신이 틀린 엔터티를 보냈다" 는 것을 의미합니다 409.

달리 말하면 422, 요청 메시지가 격리 된 것으로 간주되는 문제를 409나타내며 , 여기서 요청 메시지는 자원의 현재 상태와 충돌 함을 나타냅니다.

422에 대한 Ben Nadal의 토론은 고려하는 것이 유용 할 수 있습니다.


5
" 도메인을 문서 저장소처럼 보이도록 조정하고 있습니다. "-사람들이이 글을 읽고 REST를 결정 하기 전에 모든 결과와 의미 완전히 이해하고 싶습니다 . 정말.
JensG

"비즈니스 로직 오류"는 "유효하지 않은 입력"처럼 들립니다. 일반적으로 400 오류가 발생합니다. 더 구체적인 오류 코드는 없습니다. 유효하지 않은 입력이 아닌 경우 서버에 버그가 있고 500이 적합합니다. 귀하의 답변은 "비즈니스 로직 오류"의 특성에 대해 너무 많이 가정하는 것 같습니다.
jpmc26

422를 사용합니다. 입력이 유효하므로 400은 올바른 오류 코드가 아닙니다
Konrad

19

내 경험상 HTTP 오류 코드는 비즈니스 오류를 나타내는 데 충분하지 않습니다. 그러나 오류 클래스를 나타내는 데 유용합니다.

따라서 권장 사항은 오류 범주에 HTTP 오류 코드를 사용하는 것이지만 비즈니스 논리 오류에 대한 특정 오류 (예 : 409 충돌 ... 200 오해의 소지가 있음)를 선택하고 특정 비즈니스 오류를 나타내는 응답에 데이터를 포함시키는 것이 좋습니다. . 일부 브라우저는 사용자 정의 상태 텍스트를 무시하므로 응답 텍스트의 일부이며 상태 텍스트가 아닌지 확인하십시오. 내가 사용하는 언어에는 메시지를 표현하는 데 편리한 유니온 유형이 있습니다. 그러나 오류의 경우 문자열 상수를 정의 할 수도 있습니다.

// error with text response
409 Conflict "safety_lock_engaged"
409 Conflict "customer_not_eligible_for_selected_discount"
// warning with JSON response
202 Accepted { "backorderedProductIds": [ 37, 476 ] }

400 이상의 4xx 상태 코드는 매우 특정한 의미를 갖습니다. 귀하의 사건이 다른 사람에게 구체적으로 적용되지 않는 경우 400을 선택하십시오.
jpmc26

@ jpmc26이 방법으로 상태 코드를 사용하지 않으면 절대 사용되지 않습니다. 그러나 귀하의 답변에 옳고 적절한 방법으로 자유롭게 사용하십시오.
Kasey Speakman

어떤 의미에서는 당신이 옳습니다. 그들은 결코 사용되지 않습니다. 특정 코드에 대해 선택된 의미는 대부분의 응용 프로그램에서 일반적인 사용 사례가 아닌 것 같습니다. 괜찮아요. 우리가 잡을 코드를 작성하지 않는 많은 예외가 있습니다.
jpmc26

@ jpmc26 예외가 가장 큰 모델아닙니다 . 그러나 계속하십시오.
Kasey Speakman

특정 예외 유형 을 던지거나 잡지 않는 것은 특정 HTTP 코드 또는 다른 오류 코드를 사용하지 않는 것과 유사합니다. 나는 이것이 명백 할 것이라고 생각했다. 예외 모델이 "최고"인지의 여부는 요점과 전혀 관련이 없습니다.
jpmc26

5

일반적으로 특정 비즈니스 논리 오류 를 나타내는 데 HTTP 상태 코드를 사용하지 않는 것이 좋습니다. 이는 이미 전세계 표준에 의해 정의 된 의미 적 의미를 갖기 때문입니다. 다른 시스템, 새로운 개발자 등은 표준 편차로 인해 혼란 스러울 것입니다.

최근의 비슷한 연구에서 찾은 것은 일반적으로 400 Bad Request유효성 검사 오류 등의 경우 사용하는 것이 허용된다는 것입니다 . 이런 식으로, 당신은 하나 를 사용 모든 비즈니스 로직 오류에 대해 상태 코드를 합니다.

덧붙여, 409자원이 문서를 편집하는 동안 변경하고 다시 저장하려고 경우에 사용한다.


4

"잘못된 요청"을 사용하고 위반 된 비즈니스 규칙의 ID와 응답 본문에 대한 자세한 내용을 포함시킬 수 있습니다.


나는 이것이 유권자 투표권에 대해 모른다. 기업이 비즈니스 예외를 반환 할 수있는 방법입니다.
Skadoosh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.