RESTful 응답에서 "결과 없음"이 오류 여야합니까?


52

예를 설명하겠습니다 :
제빵 소용 API를 만들기 시작합니다. 이 API를 사용하면 집에서 만든 민트 초콜릿 칩 쿠키와 같은 베이킹 제품에 대한 카탈로그를 검색 할 수 api.examplebakery.com/search?q=.....있습니다.

누군가 이것을 사용하여 명명 된 제품을 pineapple-banana flavoured cookies찾고 결과를 찾지 못할 것입니다.

이것이 오류로 반환되어야합니까? 검색이 실패하지 않았으며 API가 검색되었으며 쿠키를 찾을 수 없다는 결론을 내 렸습니다. 404API가 실제로 발견되었으므로 API가을 (를) 반환하지 않아야합니다 .




3
@ gnat : 다른 질문은 여러 리소스에 대한 쿼리가 아닌 특정 리소스에 관한 것이므로 중복되지 않습니다.
Greg Burghardt

7
마찬가지로 객체 배열을 반환하는 함수가 있다고 가정합니다. 특정 사용 사례와 일치하는 객체가 없으면 예외를 통해 함수를 작성하거나 빈 배열을 반환 하시겠습니까?
복원 모니카

2
@AakashM GET 요청으로 HTTP-204를 반환하는 것은 매우 드문 일입니다. 내가 아는 한 HTTP-204는 일반적으로 POST / PUT / DELETE 요청과 같은 서버의 리소스를 수정할 때 응답으로 사용됩니다.
Radu Murzea

답변:


123

결과가 있으면 출력은 (주석에 따라 JSON) 목록입니다. 결과가없는 쿼리의 경우 출력이 정확히 같아야합니다. 단순리스트에는 0 개의 항목이 있습니다.

따라서 귀하의 답변이 일반적으로 다음과 같은 경우 :

{
    "results": [
        {
            "name": "Pancakes",
            ....
        },
        {
            "name": "French Fries",
            ....
        }
    ]
}

그런 다음 결과가 0 인 쿼리의 경우 다음과 같아야합니다.

{
    "results": []
}

결과의 "페이지"수, 해당 "페이지"에 대한 링크 등에 대한 메타 데이터도 포함하는 경우 1 개의 "페이지"가 ​​있다고 제안합니다.

HTTP 상태는 결과가있을 때와 같아야 200 OK합니다.

204 No Content또한 옵션으로 보이지만 실제로는 "콘텐츠"-빈 목록을 반환하기 때문이 아닙니다. 빈 목록이 "콘텐츠"로 계산되지 않는다고 생각되면 철자 제안을 제공하기 위해 응답을 수정하면 어떻게됩니까? 응답의 핵심은 여전히 ​​빈 목록이지만 이제 더 많은 "콘텐츠"가 있습니다.

HTTP 상태 코드에 대한 더 유용한 정보는 jpmc26의 답변을 읽어보십시오.


9
이것은 null 객체 패턴 과 같은 생각 입니다 . 오류와 null이 여기에 아무것도 없다고 말하는 유일한 방법은 아닙니다. 때로는 아무 것도 조용히 표현하고 싶지 않습니다. 그렇게하면 클라이언트는 아무것도 테스트 할 필요가 없습니다.
candied_orange

54
콘텐츠를 반환 할 때 204를 반환하는 것은 부적절하다고 주장합니다. 컨텐츠에 결과가 없다는 것만으로 컨텐츠를 전혀 반환하지 않는 것과 다릅니다.
TMN

9
@TMN 동의-204는 "결과 없음"에 적합하지 않습니다. 쿼리는 항상 배열 내부의 결과와 함께 배열을 반환해야합니다. 결과가 없으면 클라이언트는 자연스럽게 처리합니다. 고객이 특수 텍스트 ( "결과가 없습니다")를 표시하려면 문제가 없습니다. 204는 자연스럽게 결과를 리턴하지 않는 엔드 포인트에 대해서만 리턴되어야합니다.
JasonB

1
빈 문자열로 직렬화 된 null을 반환하는 경우 204를 사용할 수 있습니다.
Ewan

15
이. RESTful API를 구성 할 때 중요한 것은 나머지 부분이 아니라 API 부분입니다. 좋은 API는 고객 / 소비자에게 인생을 쉽게 만듭니다. 빈 배열은 null 값 / 예외 / 상태 코드보다 처리하기 쉽습니다.
구란

37

HTTP 코드를 결정할 때마다 항상이 질문을해야합니다.

임의의 클라이언트가 응답으로 무엇을 할 수 있습니까?

  1. 클라이언트가 항상 응답을 실패로 처리 해야합니까 ? 그런 다음 문제가 클라이언트의 입력인지 아니면 서버의 프로세스인지에 따라 4xx 또는 5xx를 원합니다.
  2. 클라이언트가 다른 곳에서 요청을해야합니까? 그렇다면 3xx는 당신을위한 것입니다.
  3. 서버가 클라이언트가 요청한 (성공한) 작업을 수행 했습니까? 2xx입니다.

항상 응답 코드의 범위를 먼저 결정하십시오. 그렇게하면 옵션으로 많은 응답 코드가 제거되며, 코드의 의미를 따르는 것이 훨씬 더 간단 해집니다. 각 코드 범주가 무엇을 나타내는 지에 대한 설명은 HTTP 코드 문서 의 시작 섹션을 참조하십시오 .

이 경우 클라이언트는 유효한 기존 엔드 포인트에서 필터를 제공 한 결과 목록을 요청했으며 액세스 권한이 있습니다. 서버가 요청을 처리하고 리턴 할 적절한 데이터 (항목 없음)를 판별 할 수 있었으므로 요청이 성공했습니다. 그들이 준 필터가 모든 결과를 걸러 낸 입니다. 이것이 일부 클라이언트에게는 예상되는 결과 일 수 있기 때문에 이것이 클라이언트가 원하는 것인지 아닌지를 결정하는 것은 서버에 달려 있지 않습니다. 클라이언트 코드에 문제가있는 경우, 클라이언트의 결정, 확인 및 처리는 클라이언트의 책임입니다. 따라서 이것은 분명히 2xx입니다.

이제 질문은 "2xx?"입니다. 이것은 서버의 응답 방식에 따라 다릅니다.

  • 다른 답변이 설명하는 것처럼 빈 목록의 표현을 다시 보내 시겠습니까? 그렇다면 200을 원합니다. 200은 서버에 아무런 문제가 없으며 클라이언트가 소비 한 결과를 나타냅니다. 이것은 결과에 대한 여부에 대한 응답을 구문 분석 한 다음 빈 목록 자체를 처리하는 방법을 알아낼 수있는 가장 편리한 소비자 응답 방법입니다.
  • 204는 의미 상 잘못된 것은 아니지만 메시지 본문없이 응답해야합니다 . 이것은 모든 클라이언트 코드가 다른 HTTP 코드를 명시 적으로 확인하거나 (또는 ​​최소한 메시지 본문이없는 경우) 별도로 처리해야 함을 의미합니다. 불편하고 고객이 제대로 행동하지 않을 가능성이 높습니다.

다른 것들은 전혀 적용되지 않습니다 :

  • 201은 의문의 여지가 없습니다. 영구 리소스를 만들지 않았으며 생성 된 리소스로 위치를 반환하지 않습니다.
  • 202는 의문의 여지가 없습니다. 요청이 완료되었습니다. 백그라운드에서 처리되지 않습니다.
  • 203은 권한이있는 서버와 클라이언트간에 응답이 수정되었음을 의미합니다. RESTful 인터페이스 신뢰할 수있는 서버이므로 여기에는 적용되지 않습니다.
  • 205는 이해가되지 않습니다. 클라이언트가 아무것도 지우거나 새로 고칠 필요는 없습니다.
  • 206은 여러 응답을 통해 큰 리소스를 반환하도록 설계되었습니다. 또한 클라이언트 가 헤더 의 컨텐츠 일부를 요청 해야합니다 (쿼리 문자열을 통한 페이지 매김은 적합하지 않음). 여기에는 해당되지 않습니다.

따라서 200 또는 204 여야하고 200은 더 단순하고 강력한 클라이언트 코드로 이어질 가능성이 높습니다 (특히 빈 목록이 포함 된 일관된 응답 구조를 사용하는 경우).


5
downvoter의 의견에 관심이 있습니다. 나는 이것 중 어느 것도 논쟁의 여지가 없다고 생각합니다.
jpmc26

2
클라이언트가 204를 명시 적으로 확인해야한다고 생각하지 않습니다. 필요한 것은 null 응답 객체를 처리하는 기능입니다. "본문 분석"부분을 건너 뛰어 204를 처리하는 것은 HTTP 프레임 워크의 작업입니다. Content-Lenght 4와 body null 이있는 200 은 동일합니다.
Agent_L

1
@Agent_L 서버가 정상적인 응답과 일치하지 않는 구조로 응답하면 ( null정상적으로 목록이있는 위치에 배치 하는 것과 같이 ) 200을 사용하더라도 일관성의 이점을 얻지 못할 것입니다. 그러나 내가 설명하는 것은 응답은 일반 구조와 일치하며 결과 목록이 정상적으로 진행되는 빈 목록이 있습니다. 204는 그러한 일관된 대응을 할 수있는 기회를 없애줍니다. 또한 편리한 기능이있는 HTTP 클라이언트 라이브러리에서도 JSON 구문 분석을 명시 적으로 호출해야하는 경우가 종종 있습니다.
jpmc26

@Agent_L 특히 목록의 경우 호출자는 빈 목록에서 코드를 정상적으로 실행 (예 : 반복)하여 다른 유형의 표현을 처리하기 위해 일종의 명시 적 검사가 필요할 수 있습니다.
jpmc26

16

아니요. 404를 사용하여 '조회가 처리되었지만 일치 항목이 없습니다'를 나타내는 것은 다음과 같은 이유로 끔찍합니다.

  • 예외 처리를 기반으로하는 조건부 흐름 (예 : 예외적이지 않은 결과로 인해 클라이언트에서 예외적이지 않고 어색 할 수있는 예외를 만들고 처리하도록 함)

  • '실제'페이지 사이의 모호함을 찾을 수 없습니다. 끝점을 잘못 입력했습니다. 오류

기억해야 할 것은 항상 메시지를 직렬화 해제하는 클라이언트와 해당 클라이언트가 리턴 한 내용이 중요하다는 것입니다. 직렬화가 아닙니다.

클라이언트가 널을 리턴해야하는 경우 널 직렬화를 사용하십시오. 클라이언트가 빈 배열을 반환해야하는 경우 []를 사용하고, 클라이언트가 500을 사용하고 오류 메시지를 전달해야하는 경우


2
서버가 클라이언트가 정보로 무엇을하고 있는지를 신경 써야하는 이유는 무엇입니까? (PS : 나는 당신의 답을 내려 놓은 사람이 아닙니다).
Radu Murzea

이러한 맥락에서 '클라이언트'는 서비스를 클라이언트 응용 프로그램에 노출시키는 클라이언트 장치에서 실행되는 코드입니다. 서비스 메소드를 노출하고 서비스가 의도 한대로 결과를 리턴 할 수 있어야합니다. 통신이 작동하려면 클라이언트-서버 쌍이 필요합니다.
Ewan

3
물론 클라이언트 오류에 5xx를 사용하지 마십시오 . 이 경우 4xx를 선호하십시오.
케빈

1
그러나 대부분의 경우 "클라이언트"가 아니라 "서버"가 아니어야합니까? 요청을 처리하고 응답을 제공하는 서버입니까? 클라이언트가 응답을 처리합니까? 어떤 경우에는 클라이언트 오류가 아닌 서버 오류이기 때문에 5xx 코드는 정상입니까?
MrWhite

2
모든 오류 코드 의 문제점 은 http 내에서 의미가 있다는 것입니다. 500은 서비스가 예외를 던질 때 적합한 유일한 코드입니다
Ewan

9

@Ewan의 매우 좋은 답변을 넘어서 :

쿼리가 결과 집합을 반환하는 종류 인 경우 빈 집합은 논리적으로 하나 이상의 집합만큼 적절합니다. @Ewan이 말한 이유 때문에 일반적으로 빈 세트를 오류로 변경하는 것이 좋은 것보다 더 해롭고 단순히 불필요합니다.

쿼리가 조회하고 특정 싱글 톤 (예 : id와 정확히 일치하는 것으로 예상 됨)을 반환하는 종류 인 경우 논리적으로 적절한 응답이 없습니다.


그래, 나는 이완의 대답에서 정확히 생각했다.
Walfrat

5

데이터가 반환되지 않을 때 코드가 특별한 조치를 취해야한다고 가정하지만 그렇지 않을 수도 있습니다. 코드는 단순히 제품 수를 찾거나 결과를 목록이나 여러 가지로 추가 할 수 있습니다. 실제로 오류가있는 경우에만 사용자에게 "오류"를 제공해야합니다.


3
"실제로 오류가있는 경우에만 사용자에게"오류 "를 제공해야합니다." - 이. "검색"을 수행 할 때 빈 결과 집합은 일반적으로 "오류"가 아닙니다. 그러나 데이터베이스 연결이 실패하여 검색을 실제로 수행 할 수없는 경우 빈 결과 세트 (및 오류 없음)가 모호합니다. 이 경우 어떤 종류의 오류 상태가 적합합니다 (API 정의 방법에 따라 빈 결과 집합과 함께).
MrWhite

0

API를 사용할 때 클라이언트는 "오류"사례와 다른 "성공"사례를 처리해야합니다. 나는 선택의 여지가 없다. 따라서 클라이언트 다르게 취급하고 싶을 때와 클라이언트 동일하게 취급하고 싶을 때 성공 하면 오류를 반환해야합니다 .

이론적으로 임의의 수의 결과, 0, 1, 2 백 등을 반환 할 수있는 쿼리를 수행하면 API가 모든 결과의 전체 목록을 제공 할 때마다 "성공"을 반환해야합니다. 결과가 많은 경우 과도한 크기를 피하기 위해 일부 결과 목록을 반환했으며 다른 결과를 얻는 방법에 대해 합의 된 방법이 있습니다. 클라이언트로서 종종 더 많은 결과와 같은 결과가없는 경우를 처리하기를 원하기 때문입니다. 나는 그것을 다르게 취급 할 수 있지만 강요하고 싶지 않습니다.

값을 찾는 경우와 다릅니다. 나는 정확히 하나의 결과, 내가 찾고있는 가치를 기대합니다. 그리고 의미있는 방식으로하고 싶은 일을 계속하려면 하나의 결과가 필요합니다. 어쨌든 다른 경우를 처리해야하기 때문에 값이없는 경우 상태 404를 반환하는 것이 훨씬 더 수용 가능합니다.

요약 : 클라이언트가 0에서 큰 숫자까지 많은 수의 결과를 예상하는 경우 숫자가 0 인 경우에도 모든 결과가 전달되면 "성공"을 반환합니다. 클라이언트가 정확히 하나의 결과를 기대하면 결과가 발견되면 성공을 반환하고 결과를 찾지 못하면 오류를 반환합니다.

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