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

Mat*_*llo 1 java api rest spring http

本周早些时候,我的团队讨论了HTTP代码是否代表业务失败.

想象一下我们有一个CustomerREST API 的场景.在该API中,我们有许多操作,例如:

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

现在,想象一下我正在寻找Customer哪种情况id = 5.

没有Customer了id = 5.我应该怎么做HTTP状态代码?未找到客户是业务失败.我应该退回404 - 没有找到?我应该返回200 - OK(使用JSON正文描述不存在ID为5的客户)吗?

我们正在讨论这种行为.

Controller.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Handler.java(示例)

@ExceptionHandler(BusinessResourceNotFoundException.class)
@ResponseBody
protected ResponseEntity<Fault> handleExceptionOfBusinessResourceNotFound(BusinessResourceNotFoundException exception) {
    return new ResponseEntity<Fault>(exception.getFault(), HttpStatus.NOT_FOUND);
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,返回404 - NOT FOUND,其中正文向客户端提供更多详细信息.


从阅读HTTP/1.1规范:

404未找到

服务器未找到与Request-URI匹配的任何内容.没有
说明该病症是暂时的还是
永久性的.如果服务器
通过一些内部可配置的机制知道旧
资源永久不可用且没有转发地址,则应该使用410(Gone)状态代码.
当服务器不希望
确切地说明请求被拒绝的原因,或者没有其他
响应适用时,通常会使用此状态代码.

如果"服务器没有找到与Request-URI匹配的任何内容...",我理解返回404 - NOT FOUND将是正确的方法.,因为/ id组成了我的URI(mydomain.com/customers/ id)

我对吗?

哪一个更好/更好(如果有错误的方法)方法?

cas*_*lin 5

状态代码用于描述服务器尝试理解和满足客户端相应请求的结果.

最终,如果客户端请求表示不存在的资源,则服务器应返回404以指示该情况.它本质上是一个客户端错误,应该这样报告.

返回200会产生误导,并会导致API客户端混淆.


有时,HTTP状态代码不足以传达有关错误的足够信息.

在RFC 7807的建立是为了定义简单的JSON和XML文档格式来通知客户端的HTTP API的问题.这是报告API错误的一个很好的起点.它还定义了application/problem+json与application/problem+xml媒体类型.