응용 프로그램 수준 이벤트를 설명하기 위해 HTTP 상태 코드를 사용해야합니까?


54

내가 처리 한 여러 서버는 클라이언트가 본문에서 '성공 : 거짓'과 같은 실패를 고려해야하는 요청에 대해 HTTP 200을 반환합니다.

이것은 특히 인증에 실패한 경우 HTTP 코드를 올바르게 구현하는 것처럼 보이지 않습니다. '4xx'는 요청이 변경 될 때까지 다시 요청해서는 안된다는 것을 나타내는 반면, '5xx'는 요청이 유효하거나 재시도 할 수 있지만 성공하지 못했음을 나타냅니다. 이 경우 200 : 로그인에 실패했거나 200 : 해당 파일을 찾을 수 없거나 200 : 누락 된 매개 변수 x는 분명히 잘못된 것 같습니다.

반면에 '4xx'는 요청의 구조적 문제 만 나타내야한다는 주장을 알 수 있습니다. 따라서 200을 반환하는 것이 적절합니다. 클라이언트가 요청을 할 수 있기 때문에 401이 아닌 잘못된 사용자 / 암호가 승인되지 않았지만 잘못되었습니다. 이 주장은 서버가 요청을 처리하고 결정을 할 수 있다면 응답 코드는 200이어야하며 추가 정보를 위해 본문을 확인하는 것은 클라이언트의 몫으로 요약 될 수 있습니다.

기본적으로 이것은 선호의 문제인 것 같습니다. 그러나 그것은 불만족 스럽습니다. 따라서 누군가이 패러다임 중 하나가 더 정확한 이유가 있다면 알고 싶습니다.


9
success: false요청이 실패했음을 알고 있음을 나타냅니다. 500이되어야합니다. 잘못된 사용자 이름 / 암호와 같은 것은 401입니다. 이것은 모호하지 않습니다.
Pete


4
이것은 내가 생각하는 종교적 전쟁을 불러 일으킬 수있는 질문 중 하나입니다. RESTful API의 경우 대답은 명확하지만 HTTP가 전송 계층으로 취급되는 다른 종류의 API가 있으며 이러한 경우 응용 프로그램 오류가 해당 계층에 번지지 않아야합니다.
로봇 고트

5
어떤 http 상태를 반환할지 확실하지 않은 경우 항상 418 "I 'm a teapot"으로 가고 싶어합니다.
joshp

1
예를 들어 여러 개의 (일괄 처리 된) 요청 및 응답이 있습니다. 배치는 편안한 것이 아닙니다. 그러나 실제 효율성 문제는 종종 우아함에 대한 배치를 지원해야합니다.
rwong

답변:


35

흥미로운 질문입니다.

기본적으로 우리는 이것을 OSI 계층과 유사한 용어로 분류하는 올바른 방법으로 줄일 수 있습니다. HTTP는 일반적으로 응용 프로그램 수준 프로토콜로 정의되며 HTTP는 실제로 일반 클라이언트 / 서버 프로토콜입니다.

그러나 실제로 서버는 거의 항상 릴레이 장치이며 클라이언트는 웹 브라우저이며 컨텐츠를 해석하고 렌더링하는 역할을합니다. 서버는 단지 임의의 응용 프로그램으로 항목을 전달하고 해당 응용 프로그램은 브라우저에서 임의의 스크립트를 다시 보냅니다. 실행을 담당합니다. HTTP 상호 작용 자체 (요청 / 응답 양식, 상태 코드 등)는 대부분 방해받지 않고 가능한 한 효율적으로 임의의 콘텐츠를 요청, 제공 및 렌더링하는 방법입니다. 많은 상태 코드와 헤더는 실제로 이러한 목적으로 설계되었습니다.

응용 프로그램 별 흐름을 처리하기 위해 HTTP 프로토콜을 피기 백하려고 할 때 발생하는 문제는 다음 두 가지 옵션 중 하나가 남아 있다는 것입니다. 1) 요청 / 응답 논리를 HTTP 규칙의 하위 집합으로 만들어야합니다. 또는 2) 특정 규칙을 재사용해야하며, 우려의 분리가 희미 해지는 경향이 있습니다. 처음에는 멋지고 깨끗해 보일 수 있지만 프로젝트가 발전함에 따라 후회하게 될 디자인 결정 중 하나라고 생각합니다.

따라서 프로토콜 분리에 대해 명시 적으로 작성하는 것이 좋습니다. HTTP 서버와 웹 브라우저가 자신의 일을하자, 앱이하자 자신의 일을. 앱은 요청을 할 수 있어야하고 응답이 필요합니다. 요청 방법, 응답 해석 방법에 대한 논리는 HTTP 관점보다 복잡 할 수 있습니다.

언급 할 가치가있는이 접근법의 다른 이점은 일반적으로 애플리케이션이 기본 전송 프로토콜에 의존하지 않아야한다는 것입니다 (논리적 관점에서). HTTP 자체는 과거에 변경되었으며 이제 SPDY에 따라 HTTP 2가 시작됩니다. 앱을 HTTP 기능 플러그인 이상으로 보는 경우 새 인프라가 인수 될 때 중단 될 수 있습니다.


8
매우 통찰력이 있습니다. 여기서 가장 강력한 주장은 HTTP 상태 코드와 앱의 반환 값 사이의 (임피던스) 불일치입니다. 이것은 장기적으로 악몽이 될 수 있습니다. 또한 전송 (HTTP)과 페이로드 (앱 데이터) 간의 우려 분리를 강력하게 지원합니다. 서비스 엔드 포인트의 URL을 잘못 입력하면 404가 표시됩니다. 존재하지 않는 항목을 서비스에 요청하면 앱 특정 메시지가 표시됩니다 (문제를 해결하는 데 사용할 수있는 추가 정보가있을 수 있음).

2
URL을 잘못 입력하면 올바른 서버로 연결되지 않을 수 있으며 어떤 일 이 발생할 수 있습니다.
gnasher729

이것은 미묘한 미묘한 표정입니다. HTTP가 의사 전송 계층이되는 문제는 결정을 내리는 데 실제로 발생하는 문제라고 생각합니다. nodejs 서버를 프록시하는 nginx 또는 apache 서버가있을 때 프록시에 이미이 코드를 보내는 규칙이 있으며 백엔드가 표준을 따르는 것이 적합한 지 여부가 문제가됩니다. 이러한 경우에는 nginx가 오류를 '백엔드 다운'으로 해석 할 수 있으므로 오류 코드를 보내지 않는 설계 이유가있을 수 있습니다 .
Kagan Mattson

4
동의한다. HTTP 200 응답에서 응용 프로그램 계층 오류가보고되는 데 아무런 문제가 없습니다. 200은 HTTP 요청 / 응답 자체가 성공적 이었음을 나타내며, 그 당시 내용이나 응용 프로그램 계층 의미에 대해 아무 것도 말하지 않았습니다.
Monica와의 가벼움 경주

22

이 질문은 약간의 의견을 기반으로하지만 어느 쪽이든입니다.

내가 보는 방식으로 200은 "소프트 오류"를 제공 할 수 있습니다. API를 빌드 할 때 이러한 오류와 "하드 오류"를 구별하려고합니다.

"소프트 오류" 는 상태 코드 200으로 제공되지만 오류 설명 및 성공 상태는 포함 false됩니다. "소프트 오류"는 결과가 "예상 한"경우에만 발생하지만 가장 엄격한 의미에서는 성공하지 않습니다.

"소프트 에러"는 구현 자 에게 힌트 가된다는 점에 유의해야합니다 . 따라서 사람이 읽을 수있는 오류 메시지 및 / 또는 최종 사용자에게 피드백을 제공하는 데 사용할 수있는 일종의 코드와 같은 오류에 대한 자세한 정보 를 제공하는 것이 중요합니다 . 이러한 오류는 구현 자 (및 최종 사용자)에게 서버 측 에서 발생한 일에 대한 자세한 정보를 제공합니다 .

예를 들어 검색 기능이있는 API가 있지만 검색 중에 결과가 나오지 않는다고 가정하십시오. 이것은 잘못된 것은 아니지만 정의의 가장 엄격한 의미가 아닌 "성공"도 아닙니다.

JSON 형식의 예 :

{
    "meta" {
        "success": false,
        "message": "Search yielded no results",
        "code": "NORESULTS"
    }
    "data": []
}

반면에 "하드 오류" 는 오류에 권장되는 상태 코드와 함께 제공됩니다. 사용자가 로그인하지 않았습니까? – 403/401. 잘못된 입력? – 400. 서버 오류? – 50X. 등등.

다시 말하지만 약간의 의견 기반입니다. 어떤 사람들은 모든 오류를 똑같이 "하드 오류"로 취급하려고합니다. 검색 결과가 없습니까? 404입니다! 동전 반대편에 검색 결과가 없습니까? – 예상대로 오류가 없습니다.

고려해야 할 또 다른 중요한 요소는 아키텍처입니다. JavaScript XHR 요청 및 jQuery 또는 AngularJS를 사용하여 API와 상호 작용하는 경우 이러한 "하드 오류"는 별도의 콜백으로 처리해야하지만 "소프트 오류"는 "성공"-콜백으로 처리 할 수 ​​있습니다. 아무것도 깨뜨리지 않아도 결과는 여전히 "예상대로"입니다. 클라이언트 측 코드는 성공 상태 및 코드 (또는 메시지)를 볼 수 있습니다. 그리고 최종 사용자에게 인쇄하십시오.


2
실제로 API 수준의 오류로 분류하는 것은 흥미로운 결정입니다. 클라이언트는 자신의 재량에 따라 사용자 수준에서 예기치 않은 것으로 분류 할 수 있습니다.
중복 제거기

1
고려해야 할 사항이 많이 있습니다. 모두 API 구현에 따라 다릅니다. 또한 약간의 의견 기반이며, API가 "성공"및 / 또는 "오류"로 정의한 것에 달려 있습니다. "success": false-flag은의 더 힌트 뭔가가있어 그 구현에 있습니다. 일반적으로 내부 상태 코드 와 함께 제공 됩니다. 하나 "code": "NORESULTS"또는 숫자 코드 - 무엇이든 API의 공상의 창조자. API를 구현하는 사람은 누구나 서버에서 발생한 일에 대한 정보를 공제 할 수 있습니다.
die maus

15

API에는 두 가지 측면이 있습니다. API 구현 노력과 모든 클라이언트가 API를 올바르게 사용하려는 노력입니다.

클라이언트의 저자로서, 나는 웹 서버에 요청을 보낼 때 오류가 발생하거나 (서버와 제대로 대화하지 않음) 상태 코드가있는 회신을받을 수 있음을 알고 있습니다. 오류를 처리해야합니다. 나는 좋은 반응을 처리해야합니다. 예상되고 문서화 된 "나쁜"응답을 처리해야합니다. 다른 것은 다시 처리해야합니다.

API를 디자인 할 때 클라이언트가 처리하기 가장 쉬운 것이 무엇인지 살펴 봐야합니다. 클라이언트가 올바른 형식의 요청을 보내고 요청한 요청을 수행 할 수있는 경우 200 범위에서 답변을 제공해야합니다 (해당 범위의 200 이외의 숫자가 적절한 경우도 있음).

클라이언트가 "...와 같은 모든 레코드 제공"을 요청하고 0이 있으면 성공한 200과 0 레코드 배열이 완전히 적합합니다. 언급 한 사례 :

"로그인 실패"는 일반적으로 401이어야합니다. "파일을 찾을 수 없습니다"는 404 여야합니다. "매개 변수 x"는 500 정도 (실제로, 서버가 요청이 잘못되었다는 것을 알게되면 400, 서버가 내 요청에 완전히 혼란스럽고 무슨 일이 일어나고 있는지 모른다면). 이 경우 200을 반환하는 것은 의미가 없습니다. 그것은 단지 클라이언트의 저자로서 상태 코드를 볼 수 없으며 회신을 연구해야한다는 것을 의미합니다. 난 그냥 "상태 200, 여기에 데이터가 있습니다"라고 말할 수 없습니다.

특히 "매개 변수가 없습니다"– 그것은 내가 처리 할 수있는 것이 아닙니다 . 내 요청이 잘못되었음을 의미합니다. 내 요청이 정확하지 않은 경우 잘못된 요청을 수정하기위한 폴 백이 없습니다. 시작하기 위해 올바른 요청을 보냅니다. 이제 처리해야합니다. 200을 받고 "parameter missing"이라는 답이 있는지 확인해야합니다. 끔찍 해요

결국, 다양한 상황을 처리하기위한 12 개 또는 2 개의 상태 코드가 있으므로 사용해야합니다.


3
API에 연결할 때 유효한 엔드 포인트에 연결할 때 개인적으로 '파일을 찾을 수 없음'으로 200을 얻습니다. 그러면 HTTP 처리가 API를 처리하는 레이어로 피를 흘릴 필요가 없기 때문입니다.
whatsisname

4
"매개 변수 x가 누락되었습니다"는 클라이언트가 잘못된 일을하기 때문에 400 BAD_REQUEST 여야합니다. 서버가 잘못된 일을하는 경우 500 INTERNAL_SERVER_ERROR를 예약해야합니다. 500은 클라이언트가 다시 시도 할 수 있음을 나타냅니다. 400은 누군가가 클라이언트를 수정해야 함을 의미합니다.
로봇 고트

1
RESTful 인터페이스를 작성하는 경우 URL은 특정 오브젝트를 식별하므로 404가 적합합니다. 개념적 /customers/premium/johndoe.json으로는 데이터베이스에없는 고객과 /files/morefiles/customers.html파일 시스템에없는 페이지를 나타냅니다.
로봇 고트

@whatsisname 당신이 말하는 것은 말이 안 좋은지 엔드 포인트인지 리소스가 존재하지 않는지 확실하지 않기 때문에 의미가 있습니다. 또한 엔드 포인트가 유효한지 아닌지, 해당 주소에 자원이 없으므로 404두 경우 모두에 맞습니다.
Pete

2
내가 언급하지 않은 한 가지는 응용 프로그램 오류를 HTTP 상태 코드로 피기 백하면 정보가 손실 될 수 있다는 것입니다. 앱이 404를 반환하고 다른 것은 반환하지 않으면 API가 404를 반환했는지 또는 서버가 파일을 찾을 수 없었는지 여부를 알 수 없습니다. 디버깅에 한 단계를 더 추가 할 수 있습니다.
AmadeusDrZaius
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.