유효한 요청이지만 빈 데이터에 적합한 REST 응답 코드는 무엇입니까?


331

예를 들어 GET 요청을 실행 users/9하지만 ID가 # 9 인 사용자가 없습니다. 최고의 응답 코드는 무엇입니까?

  • 200 OK
  • 202 수락
  • 204 내용 없음
  • 400 잘못된 요청
  • 404 찾을 수 없음

19
힌트 : 사용자 9를 찾았습니까?
Chris Pfohl

42
힌트 2 : 사용자 9를 찾을 수 없습니까?
Tomasz Nurkiewicz

18
@IMB 누가 204입니까? "컨텐츠 없음"은 찾고있는 엔티티가 존재하지만 표시되지 않음을 나타냅니다. 예를 들어, ID가 15 인 블로그에 댓글이없고 블로그 번호 15의 댓글에 대해 빈 목록을 반환하지 않으려는 경우 "/ blog / 15 / comments"는 NoContent를 반환합니다. 반면에 블로그 15가 존재하면 '404를 찾을 수 없음'이 더 적합합니다.
Chris Pfohl

12
@Crisfole은 "15"가 존재 하지 않으면 '404 Not Found'가 더 적합하다 "는 의미가 아닙니다.
gdoron은 Monica

15
나는 확실히 @gdoron을했다! :) 감사. 슬프게도 나는 그것을 편집하고 고치기에는 약 3 년이 너무 늦었습니다.
Chris Pfohl

답변:


249

TL; DR : 사용 404

이 블로그를 참조하십시오 . 잘 설명되어 있습니다.

에 대한 블로그 의견 요약 204:

  1. 204 No Content HTTP 스펙에 따르면 브라우저가 '보기를 변경하지 마십시오'응답 코드로 이해해야하지만 브라우저의 응답 코드로는 크게 유용하지 않습니다.
  2. 204 No Content 이다 , 그러나 뭔가를 반환하지 않고 성공을 표시 할 수 있습니다 아약스 웹 서비스에 매우 유용합니다. (원하는 경우에 특히 DELETE또는 POST의 피드백을 필요로하지 않는).

따라서 귀하의 질문에 대한 답변은 404귀하의 경우에 사용 됩니다. 204는에 대한 응답으로 브라우저에 자주 반환해서는 안되는 특수 응답 코드입니다 GET.

도보다 적절한 다른 응답 코드 204404:

  1. 200성공적으로 가져온 모든 본문으로 반환해야합니다. 가져 오는 엔티티가 존재하지 않는 경우 적절하지 않습니다.
  2. 202서버가 오브젝트 작업을 시작했지만 오브젝트가 아직 완전히 준비되지 않은 경우에 사용됩니다. 확실히 여기에는 해당되지 않습니다. GET요청 에 대한 응답으로 사용자 9의 구성을 시작하지 않았거나 시작하지도 않습니다 . 그것은 모든 종류의 규칙을 어 깁니다.
  3. 400형식이 잘못된 HTTP 요청 (예 : 형식이 잘못된 http 헤더, 잘못 정렬 된 세그먼트 등)에 대한 응답으로 사용됩니다. 이것은 사용중인 프레임 워크에 의해 거의 확실하게 처리됩니다. 서버를 처음부터 작성하지 않는 한이 문제를 해결하지 않아도됩니다. 편집 : 최신 RFC 에서는 의미 상 유효하지 않은 요청에 400을 사용할 수 있습니다.

HTTP 상태 코드에 대한 Wikipedia의 설명 이 특히 유용합니다. www.w3.org의 HTTP / 1.1 RFC2616 문서에서 정의 볼 수도 있습니다.


8
참고 : 200 년대의 응답 코드는 성공을 나타냅니다. 400 년대의 응답 코드는 실패를 나타냅니다. 포인트 1과 2의 요약은 204응답 코드 (내용 없음)에 관한 것입니다.
Chris Pfohl

227
-1은 리턴 할 레코드가없는 성공적인 호출에 대한 응답으로 404를 반대 합니다. 웹이 아닌 앱의 API를 다루는 개발자로서, 나는 호출 한 API 엔드 포인트가 존재하지 않는 이유를 추적하기 위해 API 개발자에게 연락하는 데 몇 시간을 낭비했습니다. 실제로는 실제로 없었습니다. 보고 할 데이터. 204가 브라우저에 특히 유용하지 않은 점에 관해서는, 우리의 스마트 장치 세계에서 API 엔드 포인트의 대부분의 사용은 브라우저 기반이 아니며 AJAX를 사용할 가능성이 있기 때문에 개를 흔들리는 꼬리와 약간 같습니다. 포인트를 빼앗아 죄송합니다.
Matt Cashatt

38
@MatthewPatrickCashatt 당신이 원하는대로 downvote 무료입니다. 나는 이제 사람들이 나를 추방 하는지 이해 하지만 그 근거는 여전히 틀렸다. 404를받을 때 경로가 의미가 없다는 의미는 아니며 해당 위치에 리소스가 없음을 의미합니다. 마침표. 요청 /badurl하거나 /user/9그러한 사용자가 존재하지 않는 경우에 해당됩니다. 개발자는 '찾을 수 없음'보다 더 나은 이유 문구를 추가하여 도움을 줄 수 있지만 반드시 그럴 필요는 없습니다.
Chris Pfohl

19
@Crisfole 나는 404W3 정의 , 특히 The server has not found anything matching the Request-URI. 웹 / 애플리케이션 서버는 실제로 db 서버는 그렇지 않지만 Request-URI와 일치하는 ACTION을 발견했습니다. 그러나 또한라고 말합니다 This status code is commonly used when [...] no other response is applicable. 따라서 사용법에 대해 약간의 유효성을 검사한다고 생각합니다.
Daevin

8
나는 당신이 내가하고있는 요점을 다루고 있다고 생각하지 않습니다 : 404는 혼란 스럽습니다. 발신자에게 이유 문구 또는 응답 본문을 확인하는 것은 상태 코드를 신뢰할 수 없다는 것을 의미하며,이 경우 유용하지 않습니다.
Adrian Baker

364

빈 데이터로 204 또는 200을 선호하는 404에 강력하게 반대합니다. 또는 적어도 하나는 404와 함께 응답 엔터티를 사용해야합니다.

요청이 접수되어 올바르게 처리되었습니다. 서버에서 응용 프로그램 코드를 트리거했기 때문에 실제로 클라이언트 오류라고 말할 수 없으므로 전체 클라이언트 오류 코드 (4xx) 클래스가 적합하지 않습니다.

더 중요한 것은 404는 여러 가지 기술적 이유로 발생할 수 있습니다. 예를 들어 서버에서 응용 프로그램이 일시적으로 비활성화 또는 제거되고 프록시 연결 문제가 발생하는 등 따라서 클라이언트는 "빈 결과 집합"을 의미하는 404와 "서비스를 찾을 수 없습니다. 나중에 다시 시도하십시오"를 의미하는 404를 구별 할 수 없습니다.

치명적일 수 있습니다. 회사에서 연간 보너스로 인한 모든 직원을 나열하는 회계 서비스를 상상해보십시오. 불행히도 한 번 호출되면 404를 반환합니다. 이는 보너스를받을 사람이 아무도 없거나 현재 새로운 배포를 위해 응용 프로그램이 다운되었음을 의미합니까?

-> 데이터 품질에 관심이있는 애플리케이션의 경우 응답 엔터티가없는 404는 거의 문제가되지 않습니다.

또한 많은 클라이언트 프레임 워크는 추가 질문없이 예외를 발생시켜 404에 응답합니다. 이로 인해 클라이언트 개발자는 해당 예외를 잡아서 평가 한 다음이를 모니터링 구성 요소에 의해 발생한 오류로 기록할지 또는 무시할지 여부에 따라 결정해야합니다. 그것은 나에게도 예쁘지 않은 것 같습니다.

404에 비해 404의 장점은 요청 된 리소스를 찾지 못한 이유에 대한 정보를 포함 할 수있는 응답 엔터티를 반환 할 수 있다는 것입니다. 그러나 이것이 실제로 관련이 있다면 200 OK 응답 사용을 고려하고 페이로드 데이터에서 오류 응답을 허용하는 방식으로 시스템을 설계 할 수도 있습니다. 대안 적으로, 구조화 된 정보를 호출자에게 리턴하기 위해 404 응답의 페이로드를 사용할 수있다. 예를 들어 파싱 할 수있는 XML 또는 JSON 대신 html 페이지를 수신하는 경우 이는 호출자의 관점에서 유효 할 수있는 "결과 없음"응답 대신 기술적 인 문제가 발생했음을 나타내는 좋은 지표입니다. 또는 HTTP 응답 헤더를 사용할 수도 있습니다.

여전히 나는 빈 응답으로 204 또는 200을 선호합니다. 이렇게하면 요청의 기술적 실행 상태가 요청의 논리적 결과와 분리됩니다. 2xx는 "기술적 실행은 괜찮습니다. 결과입니다. 처리합니다".

나는 빈 결과가 허용되는지 아닌지를 결정하기 위해 클라이언트에게 맡겨야한다고 생각합니다. 올바른 기술적 실행에도 불구하고 응답 엔터티없이 404를 반환함으로써 클라이언트는 단순히 오류가 아닌 오류로 간주 할 수 있습니다.

또 다른 빠른 비유 : "결과 없음"에 대해 404를 반환하는 것은 SQL 쿼리에서 결과가 반환되지 않은 경우 DatabaseConnectionException을 발생시키는 것과 같습니다. 작업을 수행 할 수는 있지만 동일한 예외를 발생시키는 유효한 기술적 인 원인이 많이 있으며 유효한 결과로 오인 될 수 있습니다.


30
'찾을 수 없음'에 대한 기술적 이유는 서버 오류라고도합니다. 그것들은 500 년대에 있어야합니다. 구체적으로 : "서비스를 찾을 수 없습니다"는 503 Service Unavailable입니다.
Chris Pfohl

43
또한 단일 사용자 ( /users경로가 아니라 /users/9"# 9"로 알려진 사용자)와 같은 특정 리소스에 대한 질문도 있었으므로 '빈 결과 집합'비교는 의미가 없습니다. 404는 객체가 존재하지 않음을 의미합니다.
Chris Pfohl

29
404는 요청 된 자원 (이 경우 사용자 번호 9)을 찾을 수 없음을 나타냅니다. 응용 프로그램 코드의 실행 여부와 관련이 없으며 백엔드 응용 프로그램의 응답 여부와 관련이 없습니다. 웹 서버는 질문에 관한 것이었고, 질문에 리버스 프록시에 대한 언급은 없었습니다.
Chris Pfohl

29
이 답변의 추론은 끔찍하게 잘못되었습니다.
커트 스핀들러

20
404 : 클라이언트가 지정된 서버와 통신 할 수 있지만 서버가 요청한 것을 찾을 수 없습니다. 말 그대로 : 요청이 접수되었으며, 요청이 정확하고 올바르게 형식화되었거나 (잘못된 요청 400), 인증 또는 공개 (권한 없음 401 / 금지 403), 지불이 필요하지 않음 (지불이 필요함 402), 요청 방법이 양호 함 (방법이 허용되지 않음 405) ), 요청 수락이 만족 될 수있다 (허용되지 않는 406). 사용자가 리소스를 얻을 때 200 Ok를 사용해야합니다. 공란은 자원이 아니다. 400 범위는 클라이언트 오류에 대한 것입니다. 500 범위는 서버 오류에 대한 것입니다. 요약 : 추론이 해제되었습니다.
Derk-Jan

62

처음에는 204가 의미가 있다고 생각했지만 토론 후에 404가 유일한 정확한 응답이라고 생각합니다. 다음 데이터를 고려하십시오.

사용자 : John, Peter

METHOD  URL                      STATUS  RESPONSE
GET     /users                   200     [John, Peter]
GET     /users/john              200     John
GET     /users/kyle              404     Not found
GET     /users?name=kyle`        200     []
DELETE  /users/john              204     No Content

일부 배경 :

  1. 검색은 배열을 반환하지만 일치하는 항목은 없지만 빈 배열 이라는 내용이 있습니다 .

  2. 404는 물론 요청 된 서버에서 지원하지 않는 URL로 가장 잘 알려져 있지만 누락 된 리소스는 실제로 동일합니다. 와 일치
    하더라도 사용자 Kyle은 사용 가능한 자원이 아니므로 404가 계속 적용됩니다. 검색어가 아니며 동적 URL에 의한 직접 참조 이므로 404입니다./users/:nameusers/kyle

어쨌든 내 두 센트 :)


9
REST API에 대해이 스타일 뒤에 체중을 던졌습니다. 어떤 클라이언트 / 사용자 요구하지해야 / 카일 그것은 자원 / 사용자 나 / 사용자 이름 = 카일 중 하나에 대한 호출을 통해 존재한다고 들었다 않는?
게리 바커

@GaryBarker 그러나 어떤 종류의 "사용자 입력"이기 때문에 API는 여전히 올바르게 처리해야합니다. 클라이언트에서 404를 방지해야하지만 실제로는 404가 처음에 확인되었음을 보장 할 수 없습니다. 클라이언트의 정확한 구현, 특히 확인 된 사용자 입력의 측면을 고려하지 않고 API를 설계해야합니다.
RicoBrassers

이것이 제가 가장 동의하는 답변입니다. API 작동 방식에 대한 완벽한 예입니다. @GaryBarker의 의견도 완벽합니다. ID로 무언가를 찾을 때 오류이며 존재하지 않습니다. 전화를 걸기 전에 ID가 존재한다는 것을 알아야합니다. 대부분 '성공적인'빈 응답을 얻으면 user.name 또는 무언가를 할 때 '정의되지 않은 속성 이름을 읽을 수 없습니다'라는 오류가 발생합니다.
Jamie Twells

이 둘의 조합은 어떻습니까? 사용자에게 친구가 있다고 가정합니다. / users / kyle / friends? name = fred. Kyle은 존재하지 않으므로이 응답은 404입니까? 우리는 kyle에 대해 정확히 신경 쓰지 않기 때문에 200입니까? fred라는 이름의 친구를 찾는 것에 만 관심이 있습니까?
JSextonn

유효하지 않은 요청이므로 404를 생성하는 IMO : Kyle이 존재하지 않으므로 친구를 검색 할 수도 없습니다.
Justus Romijn

23

리소스가 존재하지만 비어있을 것으로 예상되는 경우, 물건이 비어 있음을 나타내는 표현으로 200 OK를 얻는 것이 더 쉬울 수 있다고 주장합니다.

그래서 나는 / things가 전혀 아무것도없는 204보다 { "Items": []}로 200 OK를 반환하고 싶습니다. 이런 식으로 0 개의 아이템을 가진 컬렉션은 하나 또는 더 많은 항목이 있습니다.

204 PUT 및 DELETE에 대한 내용 없음을 그대로 두겠습니다. 실제로 유용한 표현이 없을 수 있습니다.

/ thing / 9가 실제로 존재하지 않는 경우 404가 적합합니다.


1
RPC라는보다 추상적 인 형식을 사용하여 API에 대해 프로그래밍하는 것을 선호하는 것 같습니다. customers/1/addressbookRPC 방식 은와 같은 동사와 리소스 기반 URL을 밀접하게 따라 리소스에 액세스하는 대신 엔드 포인트를 호출 GetCustomerAddressBook하여 데이터를 받거나 본질적으로 null을 가져와 HTTP의 복잡성에 대해 크게 걱정할 필요가 없습니다. 둘 다 장단점이 있습니다.
머핀 맨

2
@ The Muffin Man, REST 또는 RPC를 선호하는지 여부를 알 수있는 척하는 방법이나 HTTP GET 요청으로 반환되는 상태 코드에 대한 토론과 관련이있는 이유를 잘 모르겠습니다.
j0057

204를 사용할 때 약간의 캐싱 문제가 발생했습니다. Chrome은 요청을 이상하게 처리하고 네트워크에 아무것도 표시하지 않고 이전 결과를 캐시했습니다. 세계의 모든 캐시없는 헤더에서도 마찬가지입니다. 이 답변에 동의합니다. 빈 배열 / 객체가 사용자에게 전달되면 200이 가장 좋습니다.
Jack

22

이전 프로젝트에서는 404를 사용했습니다. 사용자 9가 없으면 개체를 찾을 수 없습니다. 따라서 404를 찾을 수 없습니다.

개체가 있지만 데이터가없는 경우 204 콘텐츠가 적합하지 않습니다. 나는 당신의 경우에는 객체가 존재 하지 않는다고 생각합니다.


14

w3 post 에 따르면

200 OK

요청이 성공했습니다. 응답과 함께 리턴 된 정보는 요청에 사용 된 방법에 따라 다릅니다.

202 수락

처리 요청이 승인되었지만 처리가 완료되지 않았습니다.

204 내용 없음

서버가 요청을 이행했지만 엔티티 본문을 리턴 할 필요가 없으며 업데이트 된 메타 정보를 리턴 할 수 있습니다.

400 잘못된 요청

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

401 무단

요청에는 사용자 인증이 필요합니다. 응답에는 반드시 WWW-Authenticate 헤더 필드가 포함되어야합니다

404 찾을 수 없음

서버가 Request-URI와 일치하는 것을 찾지 못했습니다. 상태가 일시적인지 영구적인지에 대한 표시가 없습니다.


w3 게시물은 HTTP 상태 코드에 관한 것입니다. HTTP는 REST와 동일하지 않습니다. REST는 주로 전송 프로토콜로 HTTP를 사용하지만 반드시 그런 것은 아닙니다. 404는 HTTP 전송 오류 코드입니다. REST가 HTTP와 동일 할 경우 HTTP라고해서는 안됩니까?
anneb

1
@anneb 당신이 말했듯이 REST는 HTTP를 사용 하므로이 대답은 전적으로 의미가 있습니다. REST는 HTTP가 아니며 REST는 프로토콜이 아닙니다. 이 답변이 이해되지 않기 위해 REST가 동일하거나 HTTP와 동일 할 필요는 없습니다.
Koray Tugay

@ Koray Tugay : Google 검색도 http를 사용 하므로이 답변에 따르면 Google 검색은 검색과 일치하는 항목이 없으면 http 상태 404로 응답해야합니까?
Anneb

@anneb Google 검색에서 RESTful 애플리케이션을 언급 했습니까? 나는 그렇게 생각하지 않습니다. 따라서 대답은 '아니오'입니다. 토끼 구멍에 빠지지 않고 원래 질문 과이 답변으로 다시 돌아갑니다. Google 검색에서 언젠가 RESTful API를 만들면 (아마도 이미 모르는 경우) 204 No Content결과를 찾지 못하면 반환 될 수 있습니다 . 아니 404, 그것은 당신을 위해 결과가 있지만, 내용이 없습니다 ..
Koray Tugay

13

요약하거나 단순화하기 위해

2xx : 선택적 데이터 : 올바른 형식의 URI : 기준이 URI의 일부가 아님 : 기준이 선택적인 경우 @RequestBody에 지정할 수 있으며 @RequestParam은 2xx로 이어집니다. 예 : 이름 / 상태로 필터링

4xx : 예상 데이터 : 형식이 잘못된 URI : 기준이 URI의 일부 임 : @PathVariable에만 지정할 수있는 기준이 필수 인 경우 4xx로 연결되어야합니다. 예 : 고유 한 ID로 조회

따라서 요청 된 상황의 경우 : "users / 9"는 4xx (아마 404)이지만 "users? name = superman"의 경우 2xx (아마도 204) 여야합니다.


12

두 가지 질문이 있습니다. 제목에 하나, 예제에 하나 나는 이것이 어떤 대응이 적절한 지에 대한 분쟁의 양을 초래했다고 생각한다.

질문 제목은 빈 데이터에 대해 묻습니다. 빈 데이터는 여전히 데이터이지만 데이터가없는 것과 다릅니다. 따라서 결과 집합, 즉 목록을 요청하는 것이 좋습니다 /users. 목록이 비어 있으면 여전히 목록입니다. 따라서 204 (No Content)가 가장 적합합니다. 방금 사용자 목록을 요청하고 사용자 목록을 제공했지만 내용이 없습니다.

제공된 예제는 대신 특정 객체 인 사용자에 대해 묻습니다 /users/9. 사용자 # 9를 찾지 못하면 사용자 개체가 반환되지 않습니다. 특정 자원 (사용자 오브젝트)을 요청했지만 찾을 수 없기 때문에 제공되지 않았으므로 404가 적합합니다.

조건부 문을 추가하지 않고 예상대로 응답을 사용할 수 있다면 204를 사용하고 그렇지 않으면 404를 사용하는 것이 좋습니다.

내 예제에서는 내용이 있는지 확인하지 않고 빈 목록을 반복 할 수 있지만 무언가를 깨거나 null인지 확인하지 않으면 null 객체에 사용자 객체 데이터를 표시 할 수 없습니다.

필요에 맞지만 다른 스레드에 대한 토론 인 경우 null 객체 패턴을 사용하여 객체를 반환 할 수 있습니다.


9

문제를 조사한 후 404왜 사용하지 않아야 합니까?

를 기반으로 RFC 7231 올바른 상태 코드는204

위의 답변에서 나는 작은 오해를 발견했습니다.

1.- 자원은 : /users

2.- /users/8리소스가 아닙니다. 이것은 /usersroute 매개 변수가 있는 리소스 입니다 8. 소비자는이를 알지 못하고 차이를 알지 못하지만 게시자는이를 알고 알아야합니다! ... 따라서 소비자에 대한 정확한 응답을 반환해야합니다. 기간.

그래서:

RFC 기준 : 자원 /users이 발견 되었으므로 404가 올바르지 않지만 매개 변수를 사용하여 실행 된 논리 가 응답으로 리턴 8할 항목 content을 찾지 못 했으므로 정답은 다음과 같습니다.204

여기서 중요한 점 404은 내부 논리를 처리하는 리소스조차 발견되지 않았다는 것입니다.

204는 : 리소스를 찾았고 논리가 실행되었지만 route 매개 변수에 지정된 기준을 사용하여 데이터를 찾지 못했기 때문에 아무것도 반환 할 수 없습니다. 죄송합니다. 기준을 확인한 후 다시 전화하십시오.

200: ok 리소스를 찾았습니다. 논리가 실행되었습니다 (심지어 아무것도 반환하지 않아도).이를 취하여 원하는대로 사용하십시오.

205: (GET 응답의 가장 좋은 옵션) 리소스를 찾았고 논리가 실행되었습니다. 콘텐츠가 있습니다. 잘 사용하십시오. 그것을 표시하십시오.

도움이 되길 바랍니다.


8

기존 답변이 정교하지 않은 것은 경로 매개 변수를 사용하든 쿼리 매개 변수를 사용하든 차이가 있다는 것입니다.

  • 경로 매개 변수의 경우 매개 변수는 자원 경로의 일부입니다. 의 경우 해당 리소스를 찾을 /users/9404없기 때문에 응답해야합니다 . /users/9는 리소스이며 결과는 단항 또는 오류이며 존재하지 않습니다. 이것은 모나드 가 아닙니다 .
  • 조회 매개 변수의 경우, 매개 변수는 자원 경로의 일부가 아닙니다. 의 경우 리소스 를 찾았지만 데이터를 반환 할 수 없기 때문에 /users?id=9응답해야합니다 . 리소스 가 존재하고 결과가 n-ary이며 비어 있어도 존재합니다. 경우 고유, 이것은 이다 모나드.204/users/usersid

경로 매개 변수 사용 여부 또는 쿼리 매개 변수 사용 여부는 사용 사례에 따라 다릅니다. 필자는 필수, 규범 또는 식별 인수에 대한 경로 매개 변수와 선택적, 비 규범 또는 기여 인수에 대한 쿼리 매개 변수 (페이징, 데이터 정렬 로캘 및 항목)를 선호합니다. REST API 에서 첫 번째 공개 ssh 키 를 얻거나 세 번째 우편 주소 를 얻는 것과 같은 "자식 레코드"를 얻는 중첩 가능성 때문에 특히 사용 /users/9하지 않을 것 입니다./users?id=9/users/9/ssh-keys/0/users/9/address/2

404를 선호합니다. 이유는 다음과 같습니다.

  • 단항 (1 결과) 및 n- 항 (n 결과) 메소드에 대한 호출은 특별한 이유가 없어야합니다. 가능한 경우 동일한 응답 코드를 사용하고 싶습니다. 예상되는 결과의 수는 물론 차이입니다. 예를 들어 본문이 객체 (단항) 또는 객체 배열 (n-ary) 일 것으로 예상합니다.
  • n-ary의 경우 배열을 반환하고 결과가없는 경우 세트를 반환하지 않습니다 (문서 없음). 빈 세트 (빈 문서, JSON의 빈 배열 또는 XML의 빈 요소와 같은 빈 문서)를 반환합니다 ). 즉, 여전히 200이지만 레코드는 없습니다. 이 정보를 신체 이외의 와이어에 넣을 이유가 없습니다.
  • 204void방법 과 같습니다 . 나는 그것을 사용하지 것이다 GET에만, POST, PUT,와 DELETE. GET식별자가 경로 매개 변수가 아닌 쿼리 매개 변수 인 경우 예외를 만듭니다 .
  • 기록을 발견하지 않으면처럼 NoSuchElementException, ArrayIndexOutOfBoundsException또는 존재하지 않기 때문에, 그것은 클라이언트 오류의 ID를 사용하여 클라이언트에 의한처럼 뭔가.
  • 코드 관점에서 얻는 204것은 코드에서 피할 수있는 추가 분기를 의미합니다. 클라이언트 코드를 복잡하게 만들고 경우에 따라 서버 코드를 복잡하게 만듭니다 (엔티티 / 모델 모나드 또는 일반 엔티티 / 모델 사용 여부에 따라 엔티티 / 모델 모나드를 피할 것을 강력히 권장 합니다. 모나드 중 작업이 성공했다고 생각하고 실제로 다른 것을 반환해야했을 때 200 또는 204를 반환합니다.
  • 2xx는 서버가 클라이언트가 요청한 작업을 수행했다는 것을 의미하고 4xx는 서버가 클라이언트가 요청한 작업을 수행하지 않았으며 클라이언트의 결함임을 의미하는 경우 클라이언트 코드를 작성하고 이해하기가 더 쉽습니다. 클라이언트가 존재하지 않는 ID를 요청했기 때문에 클라이언트가 id로 요청한 레코드를 클라이언트에게 제공하지 않는 것은 클라이언트의 결함입니다.

마지막으로 : 일관성

  • GET /users/9
  • PUT /users/9DELETE /users/9

PUT /users/9그리고 DELETE /users/9이미 반환해야 204성공 갱신 또는 삭제의 경우. 사용자 9가 존재하지 않을 경우 어떻게해야합니까? 사용 된 HTTP 메소드에 따라 동일한 상황이 다른 상태 코드로 표시되는 것은 의미가 없습니다.

게다가, 규범,하지만 문화적인 이유는 아니다 : 만약이 204사용되는 GET /users/9프로젝트에 일어날 다음 것은 그 사람이 돌아 생각입니다 204n 차 방법에 대한 좋은입니다. 따라서 클라이언트 코드를 복잡하게 만드는 이유 2xx는 본문을 확인한 다음 디코딩하는 대신 클라이언트 가 본문을 구체적으로 확인 204하고이 경우 디코딩을 건너 뛰어야하기 때문입니다. 클라이언트는 대신 무엇을합니까? 빈 배열을 만드시겠습니까? 그렇다면 와이어에 왜 없습니까? 클라이언트가 빈 배열을 만들면 204는 바보 압축 형식입니다. 클라이언트가 null대신 사용 하면 완전히 다른 웜 캔이 열립니다.



3

204가 더 적합합니다. 특히 웹 사이트의 보안을 보장하는 경고 시스템이있는 경우이 경우 404 경고가 백엔드 오류 또는 정상적인 요청이지만 응답이 비어 있다는 것을 모르기 때문에 혼동을 일으킬 수 있습니다.


백엔드 오류가 발생하면 404를 반환해서는 안됩니다.
appalling22

3

나는 정말로 적절하지 않다고 말하고 싶습니다. @anneb와 같이 말했듯이, HTTP 응답 코드를 사용하여 RESTful 서비스와 관련된 상태를 전송하면 문제의 일부가 발생한다고 생각합니다. REST 서비스가 자체 처리에 대해 말한 모든 것은 REST 특정 코드를 통해 전송되어야합니다.

1

HTTP 서버가 전송 된 요청에 응답 할 준비가 된 서비스를 찾으면 HTTP 404로 응답하지 않아야합니다. 결국 서버에서 무언가를 찾았습니다. 요청을 처리하는 서비스.

다음 URL을 잠시 가정 해 봅시다 http://example.com/service/return/test.

  • 사례 A는 서버가“파일 시스템에서 파일을 간단하게 찾고있다”는 것입니다. 존재하지 않으면 404맞습니다. 어떤 종류의 서비스에이 파일을 정확하게 전달하도록 요청하고 해당 서비스에 해당 이름이 존재하지 않는다고 알려주는 경우에도 마찬가지입니다.
  • B의 경우 서버는 "실제"파일로 작동하지 않지만 실제로는 다른 서비스 (예 : 일종의 템플릿 시스템)에 의해 요청이 처리됩니다. 여기서 서버는 리소스에 대해 아무것도 알지 못하므로 리소스가 존재한다고 주장 할 수 없습니다 (서비스가 리소스를 처리하지 않는 한).

명시 적으로 다른 동작을 요구하는 서비스 응답이 없으면 HTTP 서버는 3 가지만 말할 수 있습니다.

  • 503 요청을 처리해야하는 서비스가 실행 중이거나 응답하지 않는 경우
  • 200 그렇지 않으면 HTTP 서버가 실제로 서비스가 나중에 무엇을 말할 것인지에 관계없이 요청을 충족시킬 수 있기 때문에;
  • 400또는 404그러한 서비스가없고 (“오프라인은 존재하지만 반대”) 다른 서비스는 없음을 나타냅니다.

2

당면한 질문으로 돌아가려면 : 가장 깨끗한 접근법은 이전에 말한 것 이외의 응답 코드를 HTTP로 사용하지 않는 것입니다. 서비스가 있고 응답하는 경우 HTTP 코드는 200이어야합니다. 응답에는 서비스가 별도의 헤더에 반환 된 상태가 포함되어야합니다. 여기서 서비스는

  • REST:EMPTY예를 들어 sth를 검색하도록 요청받은 경우. 그리고 그 연구는 공허하게 돌아 왔습니다.
  • REST:NOT FOUND그것이 sth를 위해 특별히 요구된다면. “ID- 유사”– ID 또는 항목 번호 24 등으로 파일 이름 또는 리소스 – 특정 리소스를 찾을 수 없음 (보통 하나의 특정 리소스를 요청했지만 찾을 수 없음)
  • REST:INVALID 요청의 일부가 전송 된 경우 서비스가이를 인식하지 못합니다.

(HTTP 응답 코드와 동일한 값이나 단어를 가질 수는 있지만 완전히 다릅니다.)

위의 URL로 돌아가서 서비스 B가 HTTP 서버에이 요청 자체를 처리하지 않고에 전달 함을 HTTP 서버에 표시하는 사례 B를 검사 해 보겠습니다 SERVICE. HTTP는 자신이 전달한 내용 만 제공하며 SERVICE, 그 return/test부분이 다루는 부분 에 대해서는 아무것도 모릅니다 SERVICE. 해당 서비스가 실행 중이 면 요청을 처리 할 항목찾은200 것처럼 HTTP가 반환되어야합니다 .

SERVICE(위에서 언급했듯이 별도의 헤더에서보고 싶은)에 의해 반환되는 상태 는 실제로 예상되는 작업에 따라 다릅니다.

  • 경우는 return/test특정 리소스를 요청 : 존재하는 경우의 상태를 반환 REST:FOUND; 해당 자원이 존재하지 않으면 REST:NOT FOUND; REST:GONE우리가 한 번 존재했다는 것을 알면 돌아올 수 있고 , REST:MOVED할리우드에 갔다면 알 수 있습니다.
  • 만약 return/test고려 검색 또는 필터와 같은 연산 : 결과 집합이 비어있는 경우, 요청 종류 및 상태에 빈 세트를 리턴 REST:EMPTY; 요청 된 유형의 결과 집합 및 상태REST:SUCCESS
  • if return/test에 의해 인식 된 작업이 아닌 경우 SERVICE: REST:ERROR완전히 잘못된 경우 (예 : 오타 retrun/test) 또는 REST:NOT IMPLEMENTED나중에 계획된 경우 반환 합니다 .

4

이 차이점은 두 가지를 혼합하는 것보다 훨씬 깨끗합니다. 또한 디버깅이 쉬워지고 처리가 약간 더 복잡해집니다.

  • HTTP 404가 반환되면 서버는“내가 무슨 말을하는지 모르겠다”고 말합니다. 내 요청의 REST 부분은 괜찮을지 모르지만 모든 잘못된 위치에서 par'Mach를 찾고 있습니다.
  • 반면에 HTTP 200과 REST : ERR은 서비스를 받았지만 서비스 요청에 문제가 있음을 알려줍니다.
  • HTTP 200과 REST : EMPTY에서 올바른 서버, 서버가 서비스를 찾았고 서비스에 대한 올바른 요청을 한 것입니다. 검색 결과가 비어 있습니다.

요약

HTTP 응답 코드는 결과가 HTTP에 의해 제공되는 서비스의 상태를 나타내거나 sth를 나타내는 데 사용된다는 사실에서 문제점과 논의가 발생합니다. 그것은 HTTP 서버 자체의 범위에 있지 않습니다. 이러한 불일치로 인해 질문에 대답 할 수 없으며 모든 의견에 대해 많은 토론이 필요합니다.

HTTP 서버 REALLY NOT (RFC 6919)이 아닌 서비스에 의해 처리 된 요청의 상태는 HTTP 응답 코드로 제공됩니다. HTTP 코드 (RFC 2119)에는 HTTP 서버가 자체 범위에서 제공 할 수있는 정보, 즉 서비스가 요청을 처리했는지 여부가 포함되어야합니다.

대신, 실제로 요청을 처리하는 서비스에 대한 요청 상태를 소비자에게 알리기 위해 다른 방법을 사용해야한다. 내 제안은 특정 헤더를 통해 그렇게하는 것입니다. 이상적으로는 헤더의 이름과 내용이 모두 소비자가 이러한 응답으로 쉽게 작업 할 수있는 표준을 따릅니다.


2

RFC7231-page59 ( https://tools.ietf.org/html/rfc7231#page-59 )에 따르면 404 상태 코드 응답의 정의는 다음과 같습니다.

6.5.4. 404 찾을 수 없음 404 (찾을 수 없음) 상태 코드는 원본 서버가 대상 자원에 대한 현재 표현을 찾지 못했거나 존재한다는 것을 공개하지 않을 것임을 나타냅니다. 404 상태 코드는 이러한 표현 부족이 일시적인지 영구적인지를 나타내지 않습니다. 410 (Gone) 상태 코드는 원래 서버가 구성 가능한 일부 수단을 통해 조건이 영구적 일 가능성을 알고있는 경우 404보다 선호됩니다. 404 응답은 기본적으로 캐시 가능합니다. 즉, 방법 정의 나 명시 적 캐시 제어에서 달리 명시하지 않는 한 ([RFC7234]의 4.2.2 절 참조).

그리고 의심을 가져 오는 주된 것은 위의 맥락에서 자원의 정의입니다. 동일한 RFC (7231)에 따르면 자원의 정의는 다음과 같습니다.

리소스 : HTTP 요청의 대상을 "리소스"라고합니다. HTTP는 리소스의 특성을 제한하지 않습니다. 리소스와 상호 작용하는 데 사용될 수있는 인터페이스 만 정의합니다. 각 자원은 [RFC7230]의 2.7 절에 설명 된대로 URI (Uniform Resource Identifier)로 식별됩니다. 클라이언트는 HTTP / 1.1 요청 메시지를 구성 할 때 ([RFC7230]의 섹션 5.3)에 정의 된대로 다양한 형식 중 하나로 대상 URI를 보냅니다. 요청이 수신되면 서버는 대상 자원에 대한 유효 요청 URI를 재구성합니다 ([RFC7230]의 5.5 절). HTTP의 한 가지 디자인 목표는 요청 시맨틱과 자원 식별을 분리하는 것입니다. 이는 요청 시맨틱을 요청 방법 (4 절)과 몇 가지 요청 수정 헤더 필드 (5 절)에 투자하여 가능합니다.

따라서 404 상태 코드는 빈 결과가있는 성공적인 GET 요청에 사용해서는 안됩니다 (예 : 특정 필터에 대한 결과가없는 목록)


2

그러한 것들은 주관적 일 수 있고 양쪽에 흥미롭고 다양한 주장이 있습니다. 그러나 내 의견 으로는 누락 된 데이터에 대해 404를 반환하는 것은 올바르지 않습니다 . 다음은이를 명확하게하는 간단한 설명입니다.

  • 요청 : 데이터를 주시겠습니까?
  • 리소스 (API 엔드 포인트) : 요청을받습니다. [잠재적 인 데이터에 대한 응답을 보냅니다.]

아무것도 끊어지지 않았고, 엔드 포인트가 발견되었으며, 테이블과 컬럼이 발견되어 DB가 쿼리되고 데이터가 "성공적으로"리턴되었습니다!

"성공한 응답"에 데이터가 있는지 여부에 관계없이 "잠재적"데이터에 대한 응답을 요청했으며 "잠재적"데이터에 대한 응답이 수행되었습니다. Null, 비어있는 등은 유효한 데이터입니다.

200은 우리가 한 모든 요청이 성공했음을 의미합니다. 데이터를 요청하고 있는데 HTTP / REST에 아무런 문제가 없었으며, 데이터 (비어 있지만)가 반환되면 "데이터 요청"이 성공했습니다.

200을 반환하고 요청자가 각 특정 시나리오에서 보증하는대로 빈 데이터를 처리하도록하십시오!

이 예제를 고려하십시오.

  • 요청 : 사용자 ID가 1234 인 쿼리 "침해"테이블
  • 자원 (API 엔드 포인트) : 응답을 리턴하지만 데이터가 비어 있습니다.

비어있는이 데이터는 전적으로 유효합니다. 사용자에게 위반이 없음을 의미합니다. 이것은 내가 할 수있는 것처럼 모두 유효하기 때문에 200입니다.

당신은 위반이 없으며 블루 베리 머핀을 가지고 있습니다!

이것을 404로 간주하면 무엇을 말하고 있습니까? 사용자의 위반을 찾을 수 없습니까? 문법적으로는 맞지만 REST 세계에서는 정확하지 않습니다. 성공 또는 실패는 요청에 관한 것입니다. 이 사용자에 대한 "침해"데이터를 성공적으로 찾을 수 있습니다. 유효한 상태를 나타내는 실수 인 0 개의 위반이 있습니다.


[치키 노트 ..]

제목에서 200은 정답이라고 무의식적으로 동의합니다.

유효한 요청 이지만 빈 데이터에 적합한 REST 응답 코드는 무엇입니까 ?


다음은 주관성과 까다로운 선택에 관계없이 사용할 상태 코드를 선택할 때 고려해야 할 사항입니다.

  1. 일관성 . "데이터 없음"에 404를 사용하는 경우 응답이 데이터를 리턴하지 않을 때마다 사용하십시오 .
  2. 둘 이상의 의미에 대해 동일한 상태를 사용하지 마십시오 . 리소스를 찾을 수 없을 때 404를 반환하면 (예 : API 엔드 포인트가 존재하지 않는 등) 반환 된 데이터 가없는 경우 에도 사용 하지 마십시오 . 이것은 반응을 다루는 것을 고통스럽게 만듭니다.
  3. 상황을 신중하게 고려하십시오 . "요청"은 무엇입니까? 당신이 달성하려고 무엇을 말하는가?

1

클라이언트가 응답을 켜고 그에 따라 논리를 포크 할 수있게하는 공통 열거 형으로 응답 컨텐츠를 인코딩하십시오. 클라이언트가 "데이터를 찾을 수 없음"(404)과 "웹 리소스를 찾을 수 없음"(404)의 차이점을 어떻게 구분하는지 잘 모르겠습니까? 누군가 Z / 9 사용자를 찾아 보지 말고 클라이언트가 요청이 유효하지만 데이터가 리턴되지 않은 것처럼 궁금해하도록하십시오.


1

왜 410을 사용하지 않습니까? 요청 된 리소스가 더 이상 존재하지 않으며 클라이언트는 귀하의 경우 해당 리소스에 대한 요청을하지 않을 것을 제안합니다 users/9.

410에 대한 자세한 내용은 여기 ( https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)를 참조 하십시오.


2
무엇 해당 사용자가 나중에 작성되는 경우에, 당신의 대답은이 사용자가 매우 대담한 가정 가능성 잘못이, 존재하지 않을 것이라는 점을 보장 할 수있는 제안 - '클라이언트가 요청하지 않습니다 않을 것으로 예상된다'
홀리

홀리가 말한 것. 그녀의 요점을 추가하려면 : 사용자가 존재하고 삭제 된 경우에도 410이 잘못되었습니다. 사용자가 삭제되지 않으면 어떻게됩니까? (종류의 나중에 작성되는 특별한 경우가있다.)
기독교 Hujer

410은 영구적 인 상황이어야하기 때문입니다. restapitutorial.com/httpstatuscodes.html
Akostha

1

이 스레드에서 그렇게 간단하고 잘 정의 된 것이 "의견 기반"이 된 것은 슬픈 일입니다.

HTTP 서버는 정적 웹 페이지, 검색 결과 목록, 다른 엔티티 목록, json 설명, 미디어 파일 등 모든 컨텐츠에 대한 추상화 인 "엔터티"만 알고 있습니다.

이러한 각 엔티티는 고유 한 URL (예 :

  • / user / 9-단일 엔터티 : USER ID = 9
  • / users-단일 엔티티 : 모든 사용자의 목록
  • /media/x.mp3-단일 엔티티 : x.mp3라는 미디어 파일
  • / search-단일 엔터티 : 쿼리 매개 변수를 기반으로하는 동적 콘텐츠

서버가 주어진 URL로 리소스를 찾으면 2G의 데이터, null, {}, []와 같은 내용 이 무엇이든지 상관없이 200이됩니다. 그러나 그러한 엔티티는 서버에 알려지지 않은 경우 404 "찾을 수 없음"을 반환 할 것으로 예상됩니다.

응용 프로그램에 특정 경로 모양에 대한 처리기가 있으면 오류가 아니어야한다고 생각하는 개발자가 혼동하는 것 같습니다. HTTP 프로토콜의 관점에서 서버 내부에 일치하는 엔티티가없는 한 서버 내부에서 무슨 일이 있었는지 (즉, 기본 라우터가 응답했는지 또는 특정 경로 형태에 대한 처리기인지) 중요하지 않습니다. 요청 된 URL (MP3 파일, 웹 페이지, 사용자 개체 등을 요청한 URL)은 유효한 내용 (빈 또는 기타)을 반환하며 404 (또는 410 등) 여야합니다.

혼란의 또 다른 지점은 "데이터 없음"과 "엔티티 없음"에 관한 것 같습니다. 전자는 실체의 내용에 관한 것이고 후자는 실체의 존재에 관한 것이다.

예 1 :

  • 데이터 없음 : / users는 200 OK를 반환합니다. 아무도 등록하지 않았기 때문에 본문 : []
  • 엔티티 없음 : / users 경로가 없으므로 / users는 404를 리턴합니다.

예 2 :

  • 데이터 없음 : 사용자 ID = 9가 자신의 개인 데이터를 입력하지 않았기 때문에 / user / 9는 200을 반환합니다.
  • 엔티티 없음 : 사용자 ID = 9가 없으므로 / user / 9는 404를 리턴합니다.

예 3 :

  • 데이터 없음 : / search? name = Joe는 200 OK []를 반환합니다. DB에 Joe가 없기 때문입니다.
  • 엔터티 없음 : / search? name = Joe는 404를 반환합니다. / search 경로가 없기 때문입니다.

0

응답이있는 데이터가 없기 때문에 반환하면 404는 매우 혼란 스러울 것입니다.

나에게 빈 몸통을 가진 Response Code 200은 모든 것이 완벽하지만 요구 사항과 일치하는 데이터가 없다는 것을 이해하기에 충분합니다.



0

많은 사람들에 의해 언급 된 바와 같이, 404는 오해의 소지가 있으며, 요청 URI가 존재하지 않거나 요청 된 URI가 요청 된 자원을 페치 할 수없는 경우 클라이언트가 차별하는 것을 허용하지 않는다.

200 상태는 리소스 데이터를 포함 할 것으로 예상되므로 올바른 선택이 아닙니다. 204 상태는 완전히 다른 것을 의미하며 GET 요청에 대한 응답으로 사용해서는 안됩니다.

다른 모든 기존 상태는 어떤 이유로 든 적용 할 수 없습니다.

나는이 주제가 여러 곳에서 계속 논의되는 것을 보았다. 저에게 주제에 대한 혼란을 없애기 위해 헌신적 인 성공 상태가 필요하다는 것은 고통 스럽습니다. " 209- 표시 할 리소스가 없습니다 "와 같은 것 입니다.

ID를 찾지 못하면 클라이언트 오류로 간주되어서는 안되기 때문에 2xx 상태가됩니다 (클라이언트가 서버의 DB에있는 모든 것을 알고 있다면 서버에 아무것도 묻지 않아도됩니다). 이 전용 상태는 다른 상태 사용과 관련하여 논의 된 모든 문제를 해결합니다.

유일한 질문은 RFC가 이것을 표준으로 채택하도록하려면 어떻게해야합니까?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.