【问题标题】:How to distinguish 404 between entity doesn't exist and incorrect endpoint?如何区分实体不存在和端点不正确之间的 404?
【发布时间】:2019-12-23 12:18:49
【问题描述】:

使用 REST 原则,404 似乎用于指示实体不存在。但是,客户端如何区分这种情况与完全命中不正确的端点?

我想区分“您来到正确的端点,但该实体不存在”和“您不在正确的端点”。从技术上讲,这可以使用其他响应代码、自定义标头等来区分,但我主要关注该领域的 REST 最佳实践,因此客户端尽可能简单和标准。

【问题讨论】:

  • 客户端应该如何区分,只使用错误代码,而不提前知道实体是否实际存在?能够检测实体是否存在,而不知道它是否提前存在,需要知道如何到达正确的端点,不是吗?
  • 如果 API 的 URL 结构由于某种原因发生更改,客户端应该能够判断 URL 路径有问题,而不是仅仅将其解释为实体不存在。示例:如果 URL /person/{personId} 更改为 /foo-person/{personId} 并且客户端无法区分,它将永远报告每个实体都不存在,而不是更严重的失败。跨度>

标签: rest


【解决方案1】:

我相信确定正确的端点是 REST 客户端的唯一责任。 (当然,端点解析服务可以很容易地实现。)404 错误只是意味着这个特定的端点没有托管那个特定的实体。

RESTful 设计中不需要服务器知道客户端是否与“正确”主机交互。

【讨论】:

    【解决方案2】:

    你来到了正确的端点,但是 该实体不存在

    如果 URL 没有标识资源,它怎么可能是正确的端点?我能想到的唯一可能的情况是实体已被删除,在这种情况下 410 Gone 是正确的响应。

    请记住,如果您遵循 RESTful 原则,那么 URL 应该由服务器提供,如果是,为什么服务器会分发无效的 URL?

    【讨论】:

    • a) 在 URL 端点上不存在资源和 b) 在端点上永远不存在资源(因为它在结构上是错误的端点)之间存在区别。 HATEOAS 原则只会缓和这种影响,因为并非所有资源 URL 都由服务器提供(例如:入口点)。
    • 也许另一种说明这种差异的方式是,如果向 /employee/{employeeId} 发出请求,返回一些内容说具有该 ID 的员工不存在,但如果确实存在,则很好,这是它所在的 URL。
    • 我对这种区别在实践中并不重要的可能性持开放态度。然而,这似乎很重要。如果 API 发生变化,我希望客户端正确地“失败”,而不仅仅是开始报告世界上所有实体都不存在。
    • 不要忘记 URL 对客户端完全不透明,因此不能指望它们区分不存在 34 的 /Employee/34/employeeasdf/uiop 我真的没有看到任何价值尝试返回不同的错误代码。
    • 我不认为这是不透明的问题。我认为这是客户端配置 wrt API 的问题。我认为区分您的示例将非常有价值,因为在第一种情况下,客户端配置正确并且员工不存在。在第二种情况下,客户端配置错误,但它仍然返回404,因此用户可能没有意识到它配置错误。 (不幸的是,我认为没有一个简单的解决方案不会显着偏离最佳实践——这将是一个糟糕的权衡)。
    【解决方案3】:

    假设一个框架是这样布局的:

    / -- root
    |____+
         /object
         |____+
              /members
              |____+
                   /attributes
                   |____+
                        /attribute_1
                        /attribute_2
                        ...
                        /attribute_n
    

     
    如果您的意思是希望能够区分击中的人
    /object/members/attributes/incorrect_attribute
    404 使用了所有正确的命令,但尝试检索不存在的资源)
    还有人打/object/members/big-bird
    (假设 members 本身不能成为有效端点
    [并且/object/members/attributes 也不是有效的端点])
    那么我相信您可能会返回 501 错误(未实现)或 403 错误(禁止),具体取决于您要归咎于何处。 (或者,418(我是茶壶)在这里也有效)。

    编辑:
    最后,如果 attribute_n 曾经 存在但不再存在,您可以用 410 (资源消失)进行响应。

    见:http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

    【讨论】:

    • 如果茶壶被误贴为咖啡壶会怎样?
    • @JAB;那么你应该用 424(依赖失败)作为响应,因为茶壶真的应该装茶(伯爵茶,热的 -- 最好)。
    • 让我试着这样解释一下:对于给定的服务器,所有 URL 的全域都返回 404(我们定义的 API 除外)。这与我们用于不存在的特定资源的返回代码相同。如果有人拼写错误 /objec*k*/members/attributes/attribute_1,这将返回 404。这可能不会被客户端用户很快识别,因为当真正发生更严重的“错误”时,它被解释为 attribute_1 不存在没有正确传达给客户。
    • @jnorris - 正是。如果您想传达“您的做错了”的想法(而不是“那不在这里”),那么您应该发送一个 501(“您要求在我们没有提供的方式”)或 403(“我们不会给你那个”)。
    • 我无法发送“你做错了”,因为世界上任何一个 Web 服务都会为不存​​在的 URL 世界返回 404。我无法改变这一点。当404也用于业务级别的“实体不存在”时,客户端无法区分。 (也许这个问题无关紧要?特别是考虑到“修复”的好处,它可能会被偏离最佳实践的弊端严重抵消。
    【解决方案4】:

    根据维基百科HTTP status codes page

    400 错误请求

    服务器不能或不会处理请求由于明显的客户端错误(例如,请求语法错误,大小太大,请求消息帧无效,或欺骗性请求路由)

    我个人坚持这一点——你,客户,提出了一个错误的要求,你应该为此感到难过 =)

    【讨论】:

      猜你喜欢
      • 2020-08-09
      • 1970-01-01
      • 2019-11-19
      • 2022-12-11
      • 1970-01-01
      • 2017-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多