리소스를 찾을 수 없을 때 204 또는 404 응답을 반환해야합니까?


15

토너먼트 및 일정에 대한 간단한 RESTful 서비스를 개발 중입니다. JSON 본문을 포함하는 POST 요청을 통해 토너먼트가 작성되면 토너먼트는에 삽입되어 BiMapDAO 구현에서 다음과 같이 선언됩니다.

private BiMap<String, Tournament> tournaments = Maps.synchronizedBiMap(HashBiMap.create());

토너먼트가 작성되면 연관된 문자열 ID가 리턴되므로 사용자 는 해당 토너먼트에 대한 나중에 참조 할 수 있습니다. 다음 요청을 수행하여 새 토너먼트에서 정보를 다시 얻을 수 있습니다.

GET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39

그러나 그러한 ID를 가진 토너먼트가 없으면 어떻게해야합니까? 지금까지 204 응답을 반환합니다. 글쎄, 저지는 null그 방법 중 하나에서 돌아올 때 나를 위해 그것을 하고 있습니다. 위의 경로에 해당하는 방법입니다.

@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Tournament getTournament(@PathParam("id") String id) {
    Optional<Tournament> optTournament = tournamentDao.getTournament(id);
    if (optTournament.isPresent())
        return optTournament.get();
    return null;
}

내 질문은 : 204: No Content응답 을 반환해도 괜찮 404습니까? 아니면 리소스를 찾지 못했기 때문에 응답 이어야 합니까?

404로 변경 해야하는 경우 명백한 질문 : 메소드 서명을 올바르게 변경해야합니까? 토너먼트 (유형 Tournament)가 반환되지 않을 수 있으므로 메소드가 다르게 보일 것입니다. Response대신 타입을 리턴 타입으로 사용해야 합니까?

답변:


32

HTTP 204무언가 찾았지만 비어 있음을 의미합니다 . 예를 들어 http://example.com/logs/[date-goes-here] 와 같은 요청으로 HTTP를 통해 로그 파일을 제공한다고 가정합니다 . 2015 년 5 월 18 일 :

  • http://example.com/logs/2015-05-19 는을 반환합니다 HTTP 404. 이는 로그가 없기 때문에 미래를 기록하기가 어렵 기 때문입니다.

  • 그러나 http://example.com/logs/2015-05-18HTTP 200 은 응답 내용의 로그 항목과 함께 또는 HTTP 204로그 파일이 생성되었지만 아직 기록 된 로그가없는 경우 반환합니다. 데이트.

null요청에 대한 응답으로 프레임 워크에 제공 하는 경우 항목을 찾았으며이 항목이 비어 있다고 가정합니다 HTTP 204. 대신, throw new NotFoundException();항목이 존재하지 않음을 프레임 워크에 표시하여 항목을 생성해야합니다 HTTP 404.

404로 변경 해야하는 경우 명백한 질문 : 메소드 서명을 올바르게 변경해야합니까?

아뇨 에 대한 좋은 점 throw new NotFoundException();입니다. 메소드의 실제 리턴 유형이 무엇이든 상관없이 작동합니다.


5
RFC 2616에 유의하십시오 . 204 응답은 메시지 본문을 완전히 생략 한 경우에만 사양을 준수합니다. 어느 정도까지, 204 응답의 요점은 "아니, 내가 내용을 반환하지 않은 것은 우연이 아니다"입니다. MainMa의 예를 확장하려면 : 로그 조회 도구가 텍스트 파일을 뱉어내는 경우 (예 : 로그 파일을 그대로 그대로 뱉는 로그 파일 주위의 얇은 래퍼) 빈 로그 파일에 204가 적합합니다. 응답이 빈 JSON 객체 (예 :) {content: ''}인 경우 204 응답은 부적절합니다.
Brian

" 미래를 기록하기가 어렵 기 때문에. "-이 비트는 임의의 날짜에 따라 다릅니다. 독자가 오늘이 아닌 척하는 것을 요구하지 않는 것으로 만들면 어떨까요? 2015-02-29전혀 존재하지 않는 날짜이기 때문에 사용하는 것이 더 좋을까요?
기금 모니카의 소송


1

귀하의 요청은 GET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39입니다.

경우 http://localhost:8080/eventscheduler/엔드 포인트로 존재하지 않습니다, 당신은 당신은 (리소스에 액세스를 시도 할 때 (404) 반환해야합니다 /eventscheduler/존재하지 않음). 이것은 서버에 서버가 존재 localhost:8080하지만 클라이언트 에 eventscheduler엔드 포인트 가 없음을 나타냅니다 .

경우 http://localhost:8080/eventscheduler/엔드 포인트로 존재하지만 필요한 자원을 사용할 수 없습니다하는 5XX 오류가 적합하다. 데이터베이스가 오프라인 상태 인 경우 503을 반환 할 수 있습니다. 물론 특정 인스턴스 대신 일반 500 오류를 반환 할 수도 있습니다.

경우에 http://localhost:8080/eventscheduler/존재하지만이 나타내는 것은 c15268ce-474a-49bd-a623-b0b865386f39존재하지 않는, 나는 세부 사항을 나타내는 몸 200을 반환합니다. 엔드 포인트가 존재하고 요청이 완전히 유효하며 처리 될 수 있지만 일치하는 것이 없습니다.

엔드 포인트에 대한 클라이언트 요청이 유효하지 않은 경우 다른 4xx 오류를 볼 수 있습니다. 클라이언트가 엔드 포인트 또는 401 또는 403으로 요청한 항목에 액세스 할 권한이 없음을 표시하거나 400을 사용하여 요청이 유효하지 않음을 표시 할 수 있습니다. 이 중 하나를 사용하면 추가 정보가 응답 본문에 제공 될 수 있습니다.


엔드 포인트와 리소스를 구분할 필요가 없습니다. 어떤 이유로 든 URI가 리소스와 일치하지 않으면 서버는 404를 반환해야합니다.
bdsl

올바른 사이트를 수행하는 사이트의 예는이 사이트의 응답 코드를 확인하십시오. API가 아닌 웹 사이트이지만 동일한 http 사양이 적용됩니다. softwareengineering.stackexchange.com/questions/266183385
bdsl

@bdsl 나는 그것이 틀렸다고 말할 수 있습니다. 예를 들어, 사용자 프로필을 반환 할 수있는 사용자 서비스와 상호 작용하고 있습니다. 이 엔드 포인트가 /user이고처럼 사용 되었다고 가정 해 봅시다 /user?email=test@example.com. API 소비자로서 /user어떤 이유로 서버에 존재하지 않는지 (아마도 API v2에 추가되었고 서버가 v1에 있거나 v3에서 이름이 바뀌 었는지) 전자 메일을 사용하는 사용자 인지 알고 싶습니다. test@example.com존재하지 않습니다. 첫 번째는 404이고 두 번째는 해당 전자 메일 주소를 가진 사용자가 없음을 나타내는 본문이있는 200입니다.
Thomas Owens

@bdsl 멋지지만 그것이 옳거나 최고를 의미하는 것은 아닙니다. 또한 웹 브라우저를 통한 인간 상호 작용을 위해 설계된 웹 사이트와 소프트웨어 시스템에서 사용하도록 설계된 API를 비교할 수 있다고 생각하지 않습니다.
Thomas Owens

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