我正在构建一个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 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,许多或没有内容。
无论你选择哪种模式,最重要的是保持一致——所以要得到你的团队的认可。
和大多数事情一样,“视情况而定”。但对我来说,您的做法并不坏,并且没有违背HTTP规范本身。但是,让我们弄清楚一些事情。
首先,URI应该是不透明的。即使它们对人来说是不透明的,对机器来说也是不透明的。换句话说,http://mywebsite/api/user/13和http://mywebsite/restapi/user/13之间的差异与http://mywebsite/api/user/13和http://mywebsite/api/user/14之间的差异相同,即不相同的不是同一时期。因此,404完全适合http://mywebsite/api/user/14(如果没有这样的用户),但不一定是唯一合适的响应。
You could also return an empty 200 response or more explicitly a 204 (No Content) response. This would convey something else to the client. It would imply that the resource identified by http://mywebsite/api/user/14 has no content or is essentially nothing. It does mean that there is such a resource. However, it does not necessarily mean that you are claiming there is some user persisted in a data store with id 14. That's your private concern, not the concern of the client making the request. So, if it makes sense to model your resources that way, go ahead.
There are some security implications to giving your clients information that would make it easier for them to guess legitimate URI's. Returning a 200 on misses instead of a 404 may give the client a clue that at least the http://mywebsite/api/user part is correct. A malicious client could just keep trying different integers. But to me, a malicious client would be able to guess the http://mywebsite/api/user part anyway. A better remedy would be to use UUID's. i.e. http://mywebsite/api/user/3dd5b770-79ea-11e1-b0c4-0800200c9a66 is better than http://mywebsite/api/user/14. Doing that, you could use your technique of returning 200's without giving much away.
对于这个场景,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抛出的正确消息