应该使用HTTP代码来表示业务失败吗?

时间:2018-11-07 14:15:24

标签: java spring rest api http

我的团队在本周初讨论了HTTP代码是否代表业务失败。

想象一下我们有一个Customer REST API的情况。在该API中,我们有很多操作,例如:

  • POST -mydomain.com/customers(接收JSON正文并创建新客户)
  • 获取-mydomain.com/customers/{id}(搜索特定客户)
  • 补丁-mydomain.com/customers/{id}(接收JSON正文并修补特定客户)
  • 删除-mydomain.com;customers/{id}(删除特定客户)

现在,想象一种情况,我正在寻找具有Customer的{​​{1}}。

id = 5中没有Customer。就HTTP状态代码而言,我该怎么办? 找不到客户是业务失败。我应该返回 404-未找到吗?我是否应该返回 200-确定(使用JSON正文描述ID 5的客户不存在)?

我们就该行为进行了讨论。

Controller.java (示例)

id = 5

Handler.java (示例)

@GetMapping("/customers/{id}")
public ResponseEntity<?> handleRequestOfRetrieveCustomerById(@PathVariable("id") Integer id) throws CustomerNotFoundException {
    try {
        ResponseEntity.ok(customerService.findCustomerById(id));
    } catch(CustomerNotFoundException e) {
        // log at Controller level and rethrow
        throw e;
    }
}

在此示例中,返回 404-未找到,并带有一个向客户提供更多详细信息的正文。


通过阅读 HTTP / 1.1规范

  

找不到404

     

服务器未找到与请求URI匹配的任何内容。没有
  指示条件是暂时的还是
  常驻。如果服务器
,则应使用410(消失)状态代码。   通过某种内部可配置的机制知道一个旧的
  资源永久不可用,并且没有转发地址。
  服务器不希望使用此状态代码时通常使用
  确切说明请求被拒绝的原因,或者没有其他原因
  响应是适用的。

如果“服务器未找到与 Request-URI ...相匹配的任何内容”,则表示返回 404-未找到是正确的方法。 ,因为 / id 构成了我的URI(mydomain.com/customers/id

我对吗?

哪种方法更好/正确(如果有错误的方法)?

6 个答案:

答案 0 :(得分:5)

状态代码用于描述服务器试图理解并满足客户相应请求的结果。

最终,如果客户端请求表示不存在的资源,则服务器应返回404来表明这一点。本质上这是一个客户端错误,应该这样报告。

返回200会产生误导,并会给API客户端造成混乱。


有时,HTTP状态代码不足以传达有关错误的足够信息,以提供帮助。

创建RFC 7807的目的是定义简单的JSON和XML文档格式,以将HTTP API中的问题通知客户端。这是报告API错误的一个很好的起点。它还定义了application/problem+jsonapplication/problem+xml媒体类型。

答案 1 :(得分:2)

从技术上和角度来看,从http的角度来看,如果实体名称拼写错误(用户名是客户,而不是客户),也应返回404。

因此,即使您确定“找不到客户”将导致http 404,您也不能得出结论,http 404将暗示“找不到实体发生”。

答案 2 :(得分:1)

HTTP代码存在是有原因的。凡是使用您的API的人都应该能够立即处理响应,而不必担心正文内容。

对于您而言,404(未找到)看起来非常合适。

或者,如果您始终返回200,这是否完全超出了响应代码的目的?如果您得到答复,那么您已经知道您的请求已得到一定程度的解决。

TLDR;

使用404:)

答案 3 :(得分:1)

我最近与Rest API合作了Spring Boot,在互联网上找到的最佳做法是这样的:

  • 参数null或未设置值:400 / Bad request
  • 未找到返回值(记录或列表为空):404 / Not found
  • 服务器异常(数据库错误,网络错误等):500 / Internal server error

这些链接将为您提供帮助:best practice error handlingControllerAdviceerror message

答案 4 :(得分:1)

REST API是集成域的一部分,而不是业务域。域模型会伪装成网站(又称HTTP兼容键值存储)的皮肤。

在这里,404是一个适当的选择,因为它模仿了如果您试图获取当前未存储的密钥时键值存储将返回的响应。

答案 5 :(得分:-3)

我会遵循HTTP状态代码的含义。

Wiki说(https://en.wikipedia.org/wiki/List_of_HTTP_status_codes):

  

此类状态码适用于错误似乎是由客户端引起的情况

请明确说明:mydomain.com/customers/{id}是服务器可以理解请求的有效URL。 id = 5的客户不存在的事实与“假URL”或“无法理解的请求”无关。

我认为这应该返回2xx状态代码,并在json(REST API进行的定义)中包含更多信息

相关问题