没有内容的 HTTP 获取: 这正常吗

HTTP GET 请求有状态码为 204 - No Content的响应是否正常?比如,关于 HTTPGET 应该完成什么,这在语义上是正确的吗?我知道 204 - No Content代表 好吧代表 HTTP POST-请求。对于 GET 请求,如果不返回数据,204状态码是否合适?我应该使用404,还是仅仅使用200来获得成功,但得到的回应却是空洞的?

这个问题的 用例是我为 GoogleAppEngine 编写的一个 Java 应用程序。我正在向 servlet 发送请求,但要发送回客户端的数据将通过 Channel API 套接字传输,而不是在 HTTP Response 中传输。目前,我的客户机发送一个在请求体中没有内容的 POST,并在轮询 Channel API 套接字之前等待来自 servlet 的204响应。因为在请求的主体中没有发送数据,所以我在讨论发送 GET 而不是 POST 是否更有意义。

198212 次浏览

204 No Content

The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant.

According to the RFC part for the status code 204, it seems to me a valid choice for a GET request.

A 404 Not Found, 200 OK with empty body and 204 No Content have completely different meaning, sometimes we can't use proper status code but bend the rules and they will come back to bite you one day or later. So, if you can use proper status code, use it!

I think the choice of GET or POST is very personal as both of them will do the work but I would recommend you to keep a POST instead of a GET, for two reasons:

  • You want the other part (the servlet if I understand correctly) to perform an action not retrieve some data from it.
  • By default GET requests are cacheable if there are no parameters present in the URL, a POST is not.

Your current combination of a POST with an HTTP 204 response is fine.

Using a POST as a universal replacement for a GET is not supported by the RFC, as each has its own specific purpose and semantics.

The purpose of a GET is to retrieve a resource. Therefore, while allowed, an HTTP 204 wouldn't be the best choice since content IS expected in the response. An HTTP 404 Not Found or an HTTP 410 Gone would be better choices if the server was unable to provide the requested resource.

The RFC also specifically calls out an HTTP 204 as an appropriate response for PUT, POST and DELETE, but omits it for GET.

See the RFC for the semantics of GET.

There are other response codes that could also be returned, indicating no content, that would be more appropriate than an HTTP 204.

For example, for a conditional GET you could receive an HTTP 304 Not Modified response which would contain no body content.

The POST/GET with 204 seems fine in the first sight and will also work.

Documentation says, 2xx -- This class of status codes indicates the action requested by the client was received, understood, accepted, and processed successfully. whereas 4xx -- The 4xx class of status code is intended for situations in which the client seems to have erred.

Since, the request was successfully received, understood and processed on server. The result was that the resource was not found. So, in this case this was not an error on the client side or the client has not erred.

Hence this should be a series 2xx code and not 4xx. Sending 204 (No Content) in this case will be better than a 404 or 410 response.

I use GET/204 with a RESTful collection that is a positional array of known fixed length but with holes.

GET /items
200: ["a", "b", null]


GET /items/0
200: "a"


GET /items/1
200: "b"


GET /items/2
204:


GET /items/3
404: Not Found

Http GET returning 204 is perfectly fine, and so is returning 404.

The important thing is that you define the design standards/guidelines for your API, so that all your endpoints use status codes consistently.

For example:

  • you may indicate that a GET endpoint that returns a collection of resources will return 204 if the collection is empty. In this case GET /complaints/year/2019/month/04 may return 204 if there are no complaints filed in April 2019. This is not an error on the client side, so we return a success status code (204). OTOH, GET /complaints/12345 may return 404 if complaint number 12345 doesn't exist.
  • if your API uses HATEOAS, 204 is probably a bad idea because the response should contain links to navigate to other states.