我正在构建一个REST API,但遇到了一个问题。

在设计REST API时,公认的做法似乎是,如果所请求的资源不存在,就会返回404。

然而,对我来说,这增加了不必要的模糊性。HTTP 404通常与错误的URI联系在一起。所以实际上我们在说:“要么你去了正确的地方,但那个特定的记录不存在,要么互联网上没有这样的位置!我真的不知道是哪一个……”

考虑下面的URI:

http://mywebsite/api/user/13

如果我得到404返回,是因为用户13不存在吗?还是因为我的URL应该是:

http://mywebsite/restapi/user/13

在过去,如果记录不存在,我只是返回一个带有HTTP 200 OK响应代码的NULL结果。它很简单,在我看来非常干净,即使它不一定是公认的实践。但是有没有更好的办法呢?


当前回答

404只是HTTP响应代码。在此基础上,您可以提供一个响应体和/或其他带有开发人员将看到的更有意义的错误消息的报头。

其他回答

这是我们团队最近提出的。 我们使用404 Not found与消息体和204 No Content基于下面的理由。

如果请求URI表示单个资源的位置,则使用404 Not found。当请求查询一个URI时,我们使用204 No Content

当用户13不存在时,http://mywebsite/api/user/13将返回404 http://mywebsite/api/users?id=13将返回204 no内容 http://mywebsite/api/users?firstname=test将返回204 no内容

这里的想法是,“查询路由”被期望能够返回1,许多或没有内容。

无论你选择哪种模式,最重要的是保持一致——所以要得到你的团队的认可。

404 Not Found在技术上意味着uri当前没有映射到某个资源。在您的示例中,我解释了对http://mywebsite/api/user/13的请求,该请求返回404,以暗示此url从未映射到资源。对于客户来说,这应该是谈话的结束。

To address concerns with ambiguity, you can enhance your API by providing other response codes. For example, suppose you want to allow clients to issue GET requests the url http://mywebsite/api/user/13, you want to communicate that clients should use the canonical url http://mywebsite/restapi/user/13. In that case, you may want to consider issuing a permanent redirect by returning a 301 Moved Permanently and supply the canonical url in the Location header of the response. This tells the client that for future requests they should use the canonical url.

如果资源不存在,请使用404。不要返回一个空的200。

这类似于未定义vs空字符串(例如。"")。虽然非常相似,但绝对有区别。

404表示该URI上不存在任何东西(就像编程中未定义的变量一样)。返回200且主体为空意味着这里确实存在某些东西,并且某些东西现在只是空的(就像编程中的空字符串)。

404并不意味着它是一个“坏URI”。有一些特殊的HTTP代码用于处理URI错误(例如414 Request-URI Too Long)。

统一资源标识符是指向资源的唯一指针。格式较差的URI不指向资源,因此对其执行GET操作将不会返回资源。404表示服务器没有找到任何与请求uri匹配的内容。如果你输入了错误的URI或坏的URI,这就是你的问题,也是你无法访问资源的原因,无论是HTML页面还是IMG。

对于这个场景,HTTP 404是来自REST API的响应的响应代码 比如400,401,404,422不可处理实体

使用异常处理来检查完整的异常消息。

try{
  // call the rest api
} catch(RestClientException e) {
     //process exception
     if(e instanceof HttpStatusCodeException){
        String responseText=((HttpStatusCodeException)e).getResponseBodyAsString();
         //now you have the response, construct json from it, and extract the errors
         System.out.println("Exception :" +responseText);
     }

}

这个异常块为您提供由REST API抛出的正确消息