REST API 오류 리턴 우수 사례 [닫기]


623

REST API에서 오류를 반환 할 때 모범 사례에 대한 지침을 찾고 있습니다. 새 API를 개발 중이므로 지금 어떤 방향 으로든 사용할 수 있습니다. 내 콘텐츠 유형은 현재 XML이지만 향후 JSON을 지원할 계획입니다.

예를 들어 클라이언트가 새 리소스를 추가하려고하지만 스토리지 할당량을 초과 한 경우와 같은 일부 오류 사례를 추가하고 있습니다. HTTP 상태 코드 (인증의 경우 401, 권한 부여의 경우 403, 일반 잘못된 요청 URI의 경우 404)의 특정 오류 사례를 이미 처리하고 있습니다. 나는 축복받은 HTTP 오류 코드를 살펴 보았지만 400-417 범위 중 어느 것도 응용 프로그램 특정 오류를보고하는 것으로 보이지 않습니다. 그래서 처음에는 200 OK와 특정 XML 페이로드 (예 : 우리에게 더 많은 돈을 지불하면 필요한 저장 공간을 얻을 수 있습니다!)로 응용 프로그램 오류를 반환하려고 시도했지만 생각을 멈추고 비눗물처럼 보입니다 (/ 공포에 으)). 게다가 오류 응답을 별개의 경우로 나누는 것처럼 느껴집니다. 일부는 http 상태 코드로 구동되고 다른 것은 컨텐츠 기반입니다.

그렇다면 업계 권장 사항은 무엇입니까? 모범 사례 (이유를 설명하십시오!)와 클라이언트 POV의 REST API에서 어떤 종류의 오류 처리를 통해 클라이언트 코드를보다 쉽게 ​​사용할 수 있습니까?


7
명확히하기 위해 : 반환 할 특정 HTTP 상태 코드에별로 관심이 없지만 페이로드 오류를 HTTP 상태 코드와 결합하는 것이 좋은 REST 관행인지 아니면 페이로드에만 의존하는 것이 낫습니다.
Remus Rusanu

3
REST API 디자인 핸드북 은이 주제를 잘 다룹니다.
Remus Rusanu

12
이 질문은 의견을 요구하는 것이 아니라 지침 / 권장 사항을 요구하므로 다시 열어 참조로 사용해야합니다. 2016 년에 문을 닫은 요점은 2009 년에 만들어졌으며, 400 개 이상의 투표권을 가지고 있으며 의견을 기반으로 한 기존 답변은 없습니다
Michael Freidgeim

4
대부분 언급하지는 않았지만 HTTP 오류 코드를 사용하면 문제의 주요 원인과 관련된 문제가 발생할 수 있습니다. HTTP는 전송 프로토콜이며 404는 URLon 전송 수준에 문제가 있음을 나타냅니다 (예 : 잘못된 경로). 애플리케이션이 ID로 데이터 세트를 찾을 수없는 경우 이는 애플리케이션 레벨 오류 (전송 레벨 오류가 아님)이며 404는 편안한 http 상태 코드 사용자가 제안한대로 잘못된 결론으로 ​​이어질 수 있습니다. 일반적으로 상태 코드 사용에서 전송 및 응용 프로그램 계층의 혼합을 좋아하지 않습니다.
SCI

답변:


220

그래서 처음에는 200 OK와 특정 XML 페이로드 (예 : 우리에게 더 많은 돈을 지불하면 필요한 스토리지를 얻을 수 있습니다!)로 응용 프로그램 오류를 반환하려는 유혹을 받았지만 생각을 멈추고 비눗물처럼 보입니다 (/ 공포에서 어깨를 으)).

요청에 아무런 문제가 없으면 200을 반환하지 않습니다. 에서 RFC2616 , 200 개 수단 "요청이 성공했습니다."

어떤 이유로 든 클라이언트의 저장 용량이 초과 된 경우 403 (금지됨)을 반환합니다.

서버가 요청을 이해했지만 요청 이행을 거부하고 있습니다. 승인은 도움이되지 않으며 요청을 반복해서는 안됩니다. 요청 방법이 HEAD가 아니고 서버가 요청이 이행되지 않은 이유를 공개하기를 원한다면, 엔티티에서 거부 이유를 설명해야한다. 서버가이 정보를 클라이언트가 사용할 수 없게하려면 상태 코드 404 (찾을 수 없음)를 대신 사용할 수 있습니다.

이것은 클라이언트에게 요청은 정상이지만 실패했다는 것을 알려줍니다 (200은하지 않는 것). 또한 응답 본문에서 문제 (및 해결 방법)를 설명 할 수있는 기회를 제공합니다.

다른 특정 오류 조건을 염두에 두셨습니까?


6
본문에 자세한 오류 메시지를 포함시켜야합니까? XML 코드 / 문자열 쌍? 고객이이를 가장 잘 처리하는 방법은 무엇입니까? 예를 들어 C # WebRequest 기반 클라이언트는 'Bad Request'또는 'Forbidden'을 던지고 응답 본문을 제공하지 않습니다.
Remus Rusanu

18
403 "본체"에는 오류에 대한 세부 정보가 포함되어야합니다. 고객이 정보를 사용할 준비가되었는지 여부는 또 다른 이야기입니다. 이 형식은 다른 모든 페이로드 (예 : XML, JSON)의 형식과 동일해야합니다.
Rich Apodaca 2016 년

1
... 그리고 403에 세부 정보가 반환되지 않으면 404 "대신"을 대신 사용할 수 있습니다 (하지만 가장 좋은 옵션은 아닙니다).
Rich Apodaca 2016 년

6
404 옵션은 권한이없는 사용자가 알기를 원하지 않는 응용 프로그램에 대한 세부 정보를 403에 표시 할 수있는 경우입니다. 예를 들어 관리자가 아닌 사용자가 관리자 전용 URL에 도달하면 해당 사용자를 원하지 않을 수 있습니다 관리자 등의 경우 유효한 URL임을 알 수 있습니다.이 경우 403이 전적으로 적합합니다.
Greg Campbell

16
나는 이것이 매우 도움이되지 않는 답변이라고 생각합니다. 더 중요한 측면은 상태를 단독으로 사용해야하는지 또는 오류 정보를 페이로드에 반환해야하는지 또는 둘 다에 사용해야하는지에 관한 것입니다. 그런 다음 페이로드에 정보를 추가하는 방법. 사용되는 특정 상태는 질문의 특정 측면에만 집중하고 있습니다.
나치

584

API에 맞는 HTTP 오류 코드를 선택하는 데 도움이되는 유용한 리소스 : http://www.codetinkerer.com/2015/12/04/choosing-an-http-status-code.html

기사에서 발췌 :

어디서 시작하나요:

여기에 이미지 설명을 입력하십시오

2XX / 3XX :

여기에 이미지 설명을 입력하십시오

4XX :

여기에 이미지 설명을 입력하십시오

5XX :

여기에 이미지 설명을 입력하십시오


1
422는 특히 WebDAV 확장입니다. 나는 여기에 있어서는 안된다고 생각합니다.
Mario

@Mario Ruby on Rails API에서는 여기에 지정된 조건에 따라 422를 반환하는 것이 관용적입니다. 그 접근법을 이미 따르는 많은 것들이 이미 있습니다. 422의 대체 용도는 무엇입니까?
Kelsey Hannan

정규 올드 400
Andbdrew

감사합니다. "인터넷을 격노하고 있습니까?"는 무슨 뜻입니까?
RoutesMaps.com


87

주요 선택 사항은 HTTP 상태 코드를 REST API의 일부로 처리할지 여부입니다.

두 가지 방법 모두 잘 작동합니다. 엄밀히 말하면 REST의 아이디어 중 하나는 HTTP 상태 코드를 API의 일부로 사용해야한다는 것입니다 (성공적인 작업을 위해서는 200 또는 201을 반환하고 다양한 오류 사례에 따라 4xx 또는 5xx를 반환하십시오). REST 경찰은 없습니다. 당신이 원하는 것을 할 수 있습니다. 나는 훨씬 더 비 심각한 비 REST API가 "RESTful"이라고 불렀습니다.

이 시점에서 (2015 년 8 월) API의 일부로 HTTP 상태 코드를 사용하는 것이 좋습니다. 프레임 워크를 사용할 때 과거보다 리턴 코드를 보는 것이 훨씬 쉽습니다. 특히 200이 아닌 리턴 사례와 200이 아닌 응답 본문을 과거보다 더 쉽게 확인할 수 있습니다.

HTTP 상태 코드는 API의 일부입니다

  1. 오류 조건에 맞는 4xx 코드를 신중하게 선택해야합니다. 하위 코드 및 설명 주석이 포함 된 페이로드로 나머지, xml 또는 일반 텍스트 메시지를 포함 할 수 있습니다.

  2. 클라이언트는 HTTP 레벨 상태 코드를 얻을 수있는 소프트웨어 프레임 워크를 사용해야합니다. 일반적으로 가능하지만 항상 간단한 것은 아닙니다.

  3. 클라이언트는 통신 오류를 나타내는 HTTP 상태 코드와 응용 프로그램 수준 문제를 나타내는 자체 상태 코드를 구분해야합니다.

HTTP 상태 코드는 API의 일부가 아닙니다

  1. 앱이 요청을 수신 한 후 응답 한 경우 (성공 및 오류 사례 모두) HTTP 상태 코드는 항상 200입니다.

  2. 모든 답변에는 "봉투"또는 "헤더"정보가 포함되어야합니다. 일반적으로 다음과 같습니다.

    envelope_ver : 1.0
    상태 : # 원하는 코드를 사용하십시오. 성공을위한 코드를 예약하십시오.
    msg : "ok"# 코드를 반영하는 인간 문자열. 디버깅에 유용합니다.
    data : ... # 응답의 데이터입니다 (있는 경우).
  3. 응답 상태는 항상 동일한 위치 (하위 코드 필요 없음), 코드 제한 없음, HTTP 수준 상태 코드 가져 오기 필요 없음으로 인해이 방법이 더 쉬울 수 있습니다.

비슷한 생각을 가진 게시물이 있습니다 : http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/

주요 이슈:

  1. 필요한 경우 나중에 API의 의미를 변경할 수 있도록 버전 번호를 포함하십시오.

  2. 문서...


8
타이 옵션 2 ...하지만 나머지 옷 SOAP 것 같아
레무스 Rusanu

138
아니요, 200을 통해 모든 것을 터널링하는 것은 전혀 편안하지 않습니다. 중개자가 조작 결과를 이해하지 못하게하여 모든 형태의 캐싱을 제거하고 조작의 의미를 숨기고 오류를 처리하기 위해 메시지 내용을 이해하여 자체 포함 된 메시지 제한 조건을 위반합니다.
SerialSeb 2016 년

13
200으로 오류 세부 사항을 리턴하는 것은 RESTful이 아니지만 그럼에도 유용한 답변입니다 ( "두 방법이 모두 편안합니다"라는 말을 무시하는 경우) ... 더 큰 요점은 RESTful API가 가장 적합한 옵션이 아닐 수 있습니다. OP.
MB.

3
HTTP 프로토콜로 원하는 것을 할 수 있고 여전히 "RESTy"라는 일반적인 이해가있는 것 같습니다. 작성된 프로토콜에 프로토콜을 사용하십시오. 이것이 REST의 핵심 아이디어 중 하나입니다. 따라서 상태 코드 프로토콜의 일부 여야 합니다.
Ariel M.

상태 코드의 요점은 다양한 프로그래밍 언어, 프레임 워크 및 접근 방식 간의 공통된 이해 언어를 제공하는 것입니다. 상태 코드의 의미는 보편적 인 것입니다. API 소비자가 반드시 익혀야하는 사용자 지정 구문을 통해 더 많은 복잡성을 추가하는 사용자 지정 본문은 아닙니다.
Kelsey Hannan

40

HTTP / 1.1 RFC에 정의 된 것보다 많은 상태 코드가 있음을 기억 하십시오 . IANA 레지스트리는 http://www.iana.org/assignments/http-status-codes에 있습니다. 당신이 상태 코드 507을 언급 한 경우에는 소리가납니다.


3
흠, "507 Insufficient Storage"는 한눈에보기에 적당하지만, "공용이 아닌"WebDAV 확장 용으로 의도 된 것이 아니기 때문에이를 사용하는 것에 대한 우려가 있습니다. 예외. 아직도, 나는 당신이 그것을 사용할 수 있다고 생각합니다.
Max

1
아니요, WebDAV에만 국한된 것은 아닙니다. HTTP 상태 코드에 대한 레지스트리가있는 이유가 있습니다.
Julian Reschke

25
507이 목적에 동의하지 않습니다 . 내 해석은 507서버 공간이 아니라 계정 공간이 부족하다는 것입니다.
Patrick

11
Patrick에 동의합니다. 5xx오류는 서버와 관련된 오류입니다.
Sean

10
418 : "나는 주전자입니다"는 저장 공간이 너무 크지 않고 (찻 주전자가 적음) 공간이 부족하다는 것을 의미합니다.
Steve Konves 2009

22

다른 사람들이 지적했듯이 오류 코드에 응답 엔터티를 갖는 것은 완벽하게 허용됩니다.

5xx 오류는 서버 측이므로, 클라이언트는 요청을 전달하기 위해 요청으로 아무것도 변경할 수 없습니다. 클라이언트의 할당량을 초과하면 서버 오류가 아닌 것이므로 5xx를 피해야합니다.


동의하지 않습니다. Quota Exceeded는 다음과 같은 이유로 서버 오류 (5xx)가됩니다.
mikek3332002 2

3
그러나 서버는 아무 것도 잘못하지 않았습니다.
Charlie Schliesser

20

두 가지 종류의 오류가 있습니다. 응용 프로그램 오류 및 HTTP 오류 HTTP 오류는 AJAX 핸들러에 문제가 발생했음을 알리고 다른 용도로는 사용해서는 안된다는 것입니다.

5xx 서버 오류

500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates (RFC 2295 )
507 Insufficient Storage (WebDAV) (RFC 4918 )
509 Bandwidth Limit Exceeded (Apache bw/limited extension)
510 Not Extended (RFC 2774 )

2xx 성공

200 OK
201 Created
202 Accepted
203 Non-Authoritative Information (since HTTP/1.1)
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status (WebDAV)

그러나 응용 프로그램 오류를 디자인하는 방법은 전적으로 귀하에게 달려 있습니다. 스택 오버플로는 예를 들어와 객체 발송 response, datamessage특성을. 내가 믿는 응답은 포함 true또는 false작업이 (일반적으로 쓰기 작업에 대한) 성공하면 나타냅니다. 데이터 (일반적으로 판독 동작에 대한) 페이로드를 포함하고, 메시지 (예를 들면 에러 메시지 등 추가적인 유용한 메타 데이터 또는 메시지를 포함 response이다 false).


1
400은 또한 클라이언트 응용 프로그램의 문제점을 표시하는 데 도움이됩니다.
dolmen

19

나는 이것이 파티에 매우 늦다는 것을 알고 있지만, 이제는 2013 년에 일반적인 분산 (RESTful) 방식으로 오류 처리를 다루는 몇 가지 미디어 유형이 있습니다. "vnd.error", application / vnd.error + json ( https://github.com/blongden/vnd.error ) 및 "HTTP API에 대한 문제점 세부 사항", application / problem + json ( https : // tools)을 참조하십시오. ietf.org/html/draft-nottingham-http-problem-05 ).


2
링크 주셔서 감사합니다. draft-nottingham-http-problem은 이제 제안 된 표준입니다 : datatracker.ietf.org/doc/rfc7807
seanf

9

동의했다. REST의 기본 철학은 웹 인프라를 사용하는 것입니다. HTTP 상태 코드는 HTTP 페이로드를 늘리지 않고도 당사자들이 서로 통신 할 수있는 메시징 프레임 워크입니다. 이들은 이미 응답 상태를 전달하는 범용 코드로 설정되어 있으므로 진정으로 RESTful하려면 애플리케이션이이 프레임 워크를 사용하여 응답 상태를 통신해야합니다.

HTTP 200 엔벨로프에서 오류 응답을 보내는 것은 오해의 소지가 있으며, 클라이언트 (api 소비자)가 메시지를 비표준 또는 독점적 인 방식으로 구문 분석하도록합니다. 이는 또한 비효율적입니다. 클라이언트는 "실제"응답 상태를 이해하기 위해 매번 HTTP 페이로드를 구문 분석해야합니다. 이는 처리를 증가시키고 대기 시간을 추가하며 클라이언트가 실수 할 수있는 환경을 만듭니다.


3
성공적인 응답이든 실패 응답이든 관계없이 응답을 구문 분석 할 것입니다. 오류 인 경우 구문 분석하여 오류 메시지를 표시하려고합니다. 오류 응답은 일반적으로 작고 구문 분석이 빠릅니다. 나는 파싱 오류 응답을 피하기 위해 최적화하려고하는 것에 대해 걱정할 필요가 없다고 생각합니다. 오류 응답을 파싱하지 않고 그냥 버릴 것입니까? 내 의견으로는 현명하지 않다.
AgilePro

3
200 OK를 받으면 비즈니스 규칙에 따라 구문 분석하지 않도록 선택할 수도 있습니다. 요점은 우리가 항상 파싱하는지 아닌지가 아닙니다. 요점은 의도입니다-200 OK의 의도는 무엇입니까? 200 OK에 싸인 오류 메시지를 보내서 의도를 손상시키고 있습니다.
Kingz

1
"200 OK의 의도는 무엇입니까?" -전송 계층의 성공을 표시합니다. 요청이 성공적으로 수신 및 응답되었으며 HTTP와 관련이없는 응용 프로그램 특정 문제점이있었습니다. +++ 다시 말하면 REST 세계에서 404를 보내는 것은 무언가 가 발견되지 않았거나 URL이 잘못되었거나 처리되는 자원 또는 다른 것을 찾지 못했음을 의미합니다. 메시지를 파싱하지 않으면 할 수 없습니다. IMHO REST는 단지 레이어를 병합하는 것입니다.
maaartinus

분쟁은 표준입니다. 추론에 적합한 구문을 제공하며 비즈니스 계층에 집중할 수 있습니다. 전송 후 상태 통신에 동의-그 목적은 처음에-REST는 HTTP와 동시에 발명 / 제안되지 않았습니다-나중에 와서 기존 인프라를 사용하여 STATES와 CHANGES를 나타냅니다.
Kingz


5

프로토콜의 의미를 고수하십시오. 성공적인 응답에는 2xx를 사용하고 오류 응답에는 4xx, 5xx를 사용하십시오 (비즈니스 예외 또는 기타). 프로토콜에 의도 된 유스 케이스 인 응답에 2xx를 사용했으면 처음에는 다른 상태 코드가 없습니다.


3

응용 프로그램 오류뿐만 아니라 5xx 오류도 잊지 마십시오.

이 경우 409 (충돌)는 어떻습니까? 이것은 저장된 자원을 삭제하여 사용자가 문제점을 해결할 수 있다고 가정합니다.

그렇지 않으면 507 (완전히 표준은 아님)도 작동 할 수 있습니다. 일반적인 오류에 200을 사용하지 않으면 200을 사용하지 않습니다.


-1

클라이언트 할당량을 초과하면 서버 오류이므로이 경우 5xx를 피하십시오.


2
서버 오류에 대한 5xx 시리즈 오류를 피하는 이유는 무엇입니까?
mikek3332002 2

6
'클라이언트 할당량 초과'는 서버 오류가 아니며 클라이언트 제한 사항이며 4xx 미만이어야합니다.
MyGGaN
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.