아래와 같은 URL을 Get Method로 호출했다고 가정하겠습니다
1. http://example.com/request/animal?name=pig
2. http://example.com/request/animal?name=spider
1번은 데이터가 있고 2번은 데이터가 없다고 할 때 2번은 status code로 무엇을 줘야 할까요?
해당 url path는 서버에 존재하지만 query string에 들어가는 값에 따라서 데이터가 없다면 200 ok와 empy body를 전달하면 될까요? 예전에는 이런식으로 한걸 많이 본거 같습니다. 여기에도 저처럼 그런걸 많이 봐서 고민하는 분이 계십니다.
https://stackoverflow.com/questions/9930695/rest-api-404-bad-uri-or-missing-resource
가장 마음에 드는 대답은 200 Ok를 하고 body에 empty string을 주는 건 해당 데이터가 존재하는데 그 데이터가 empty string 이라는 것입니다. 개발을 할 때 의례적으로 empty string은 값이 없다는 것으로 사용하기도 하는데 그것이 데이터가 없다는 것을 서버에게 명시적으로 알려주는게 아니라고 생각합니다.
더 명시적으로 알려주기 위해 200 대신 404를 사용하라고 답한게 있는데 돌다리도 두들기자는 심정으로 다시 정의를 살펴보려 합니다. 관련 설명은 우리에 친구 MDN에게 물어봅니다. 처음부터 RFC를 보는건 추천하지 않습니다. 거기 가면 머리만 더 복잡해지는 거 같습니다. (어디까지나 개인 의견입니다… 쿨럭)
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200The HTTP 200 OK success status response code indicates that the request has succeeded. A 200 response is cacheable by default.RFC는 요기 — https://tools.ietf.org/html/rfc7231#section-6.3.1
주로 GET, HEAD, POST, TRACE에 사용하고, PUT이나 DELETE처럼 처리 후 데이터 보내줄 필요 없는 건 204 (No Content)를 사용한다고 합니다. 데이터 없음이 empty string으로 payload를 넘기는건 명시적이라고 생각하지 않아 넘어갑니다. 본 김에 204도 둘러 봅니다.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204The HTTP 204 No Content success status response code indicates that the request has succeeded, but that the client doesn’t need to go away from its current page. A 204 response is cacheable by default. An ETag header is included in such a response.RFC는 요기 : https://tools.ietf.org/html/rfc7231#section-6.3.5
설명을 보면 요청한 Request를 성공적으로 수행한 뒤 추가적으로 컨텐츠를 보낼 필요가 없을 때 사용한다고 되어 있습니다. “204 No Content” 라는 것만 봤을 때, 아니 이걸 왜 기억 못하고 있었지? 했는데…. 일반적인 용도로는 PUT request 를 성공적으로 처리 후 페이지를 변경할 컨텐츠가 없거나 다른 페이지로 아동할 필요가 없을 때 사용한다고 되어 있습니다. resource 변경 후 추가 전달할 데이터가 일반적으로 없는 경우를 말하는 것으로 이해하였습니다. 특정 query string에 따라 전달할 데이터가 있고 없는게 아니라, 일반적으로 없는 것입니다.
이제 404를 봅니다.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404The HTTP 404 Not Found client error response code indicates that the server can’t find the requested resource. Links which lead to a 404 page are often called broken or dead links, and can be subject to link rot.RFC는 요기 : https://tools.ietf.org/html/rfc7231#section-6.5.4The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists. A 404 status code does not indicate whether this lack of representation is temporary or permanent; the 410 (Gone) status code is preferred over 404 if the origin server knows, presumably through some configurable means, that the condition is likely to be permanent.
A 404 response is cacheable by default; i.e., unless otherwise indicated by the method definition or explicit cache controls (see
Section 4.2.2 of [RFC7234]).
요청한 리소스가 없을 때 가리킵니다. 더 정확히는 요청한 리소스에 대한 현재 representation 을 찾을 수 없을 때 사용합니다. (representation 에 대한 자세한 설명은 eungjun님의 글을 참조해주세요.) 간단하게 설명하면 해당 링크가 존재하지 않는다는 뜻입니다. http://example.com/request/animal 자체가 없을 때 사용합니다.
이 때 불현듯 400이 갑자기 생각 났습니다. 궁금할 때는 언제나 우리에 친구 MDN에게 물어봅니다.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400
The HTTP 400 Bad Request response status code indicates that the server could not understand the request due to invalid syntax. The client should not repeat this request without modification.
“Request” 가 규칙에 맞게 잘 만들어졌으면 일단 통과인거 같습니다. 시간이 되면 여기도 한 번 다녀오세요.
http://tools.ietf.org/html/7231#section-6.5.1
저기에 가면 아래와 같은 문제가 발생했을 때 400을 사용하라고 알려줍니다. 대체로 Request를 규칙에 맞게 잘 만들라는 얘기입니다.
malformed request syntax, invalid request, message framing, or deceptive request routing
2번 같은 경우 URL이 규칙에 맞게 만들어졌고, Header는 브라우저에서 알아서 잘 만들어 주기 때문에 400은 아니라고 생각했을 때 쯤 누군가 406 이라는 게 있다고 속삭이며 지나갔습니다. 두둥!! 다시 친구(MDN)를 소환합니다.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406
The HTTP 406 Not Acceptable client error response code indicates that a response matching the list of acceptable values defined in Accept-Charset and Accept-Language cannot be served.RFC는 요기 : https://tools.ietf.org/html/rfc7231#section-6.5.6
뜻을 해석하면 Request가 받아들여지기 힘들다는 건데, 주로 Request header에 있는 accept 관련 값들을 다룰 때 사용합니다.
이 이야기는 자연스럽게 Content Negotiation 으로 흘러갑니다. 이 부분도 나중에 기회되면 정리하고 싶네요. 자세한 건 요기
https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation
https://tools.ietf.org/html/rfc7231#section-5.3
406은 Content Negotiation 관련해서 이슈가 있을 때 주로 사용하는 거 같습니다. 예전에는 이슈가 있어 보이지만 개인적으로 해당 이슈를 접해본 경험이 없고 좀처럼 사용을 안 한다고 합니다. 아마도 특별한 경우 외에는 직접적으로 값을 셋팅해사 사용할 일이 많지 않아서 그런거 같습니다.
결론
요청 URL (http://example.com/request/animal?name=spider) “http://example.com/request/animal” 부분은 존재하기 때문에 404는 맞지 않고 name 값에 따라서 결과가 달라지기 때문에 200이 맞아 보입니다. 하지만, 관습 or 기존 설계 등을 고려해서 다른 사람도 알아보기 좋고 전체 균형을 고려해서 사용하는게 좋을 것 같습니다.
p.s 피드백 주신 한바름님 감사합니다. 바름님이 주신 내용 참고하여 업데이트 하였습니다. 피드백은 언제나 환영입니다 ^___^
* 참고 자료
– REST API 404: Bad URI, or Missing Resource? in Stackoverflow
https://stackoverflow.com/questions/9930695/rest-api-404-bad-uri-or-missing-resource
– Status Code Definitions in rfc2616
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
– 400 Bad Request
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400
https://tools.ietf.org/html/rfc7231#section-6.5.1
– 404 Not Found
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404
https://tools.ietf.org/html/rfc7231#section-6.5.4
– 406 Not Acceptable
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406
https://tools.ietf.org/html/rfc7231#section-6.5.6
– Content Negotiation
https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation
https://tools.ietf.org/html/rfc7231#section-5.3
– 204 No Content
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204