404状态代码及其在一个普通的几乎是平静的api上的双重含义

时间:2013-10-12 17:25:11

标签: api http rest

在一个真正宁静的应用程序中,我应该按照链接来访问我的资源,而唯一的“神奇的已知URL”应该是应用程序入口点。在GET /user/john至少有一个指向/user的链接,或者来自前一个链接指定的搜索网址的结果,例如GET /user?username=john

之后,应该发出State Transfer等直接查询

但是随着以下链接强制更多功能,进一步开发时间和更智能的客户端,实际的现实是我编写和使用的大部分宁静api都是部分宁静的:它们是定义良好的URI和方法的集合,所有以前用户都知道的一些文档。最后,what REST means404部分并不存在于其中。

好吧,按照以前知道网址的现实情况,404代码变成了一个问题:如何区分GET /user/mario可能具有的2种含义:

  • correct 404表示“资源未找到,但您可以在将来重试”。示例:GET /foobar/123,而mario不是注册用户

  • api的错误用法意味着“此处未找到任何资源,您正在使用此API”。示例:406 Not Acceptable

区分这两种情况是很重要的,因为作为服务维护者,他们基本上告诉我它是否是一个期望错误而我不应该担心(第一种情况)或意外错误我应该担心作为服务与我的客户整合有问题(第二种情况)

我尝试搜索更好的状态代码来表示第二种情况,我找到的最接近的是Accept(但它是针对无法履行的410 Gone标头的响应)和State Transfer(这可能会让人感到困惑,因为没有资源存在,但好的部分是它告诉客户端永远不再尝试该URL)。尽管如此,这两者中没有一个足够好用于解决这个问题

你是怎么做的或者你会怎么解决这个问题?

边节点python eve是一个有趣的项目,试图成为{{1}}部分的宁静api。那个<{p}} implements HATEOAS

2 个答案:

答案 0 :(得分:2)

第一种情况(连同解释)使用403而第二种情况使用404怎么样?由于RFC 403将404称为替代响应代码,因此它们可能是相关的......

  

403 Forbidden:服务器理解请求,但拒绝履行请求。      授权无效,请求不应重复。如果请求方法不是HEAD并且服务器希望公开为什么请求没有得到满足,那么它应该描述实体中拒绝的原因。如果服务器不希望将此信息提供给客户端,则可以使用状态代码404(未找到)。

403:您了解客户想要的但拒绝履行。客户端不应再试一次 - 在创建此资源之前禁止它 - 您可以将其解释为答案的一部分。

404:你知道客户想要你不会提供的东西,并且可以真诚地告诉他,这个资源永远不会存在。

<强>更新

RFC 2119解释了如何解释“不应该”:

  

不应该这句话或短语“NOT RECOMMENDED”意味着      在特殊情况下可能存在有效理由      特殊行为是可以接受的甚至是有用的,但是完整的      应该理解其含义并仔细权衡案例      在实现此标签描述的任何行为之前。

我认为对你的用例来说这是真的。如果不解决403回答中所述的原因,则不应重复客户端请求:“禁止访问此资源,因为不存在名为mario的用户”。但如果客户确信原因消失了,他可以再次尝试。但这可能只是我对403“的解释不应该重复”声明。

答案 1 :(得分:1)

通过设计RFC 2616 Section 10.4.5

,无法区分这两个原因
  

10.4.5 404 Not Found

     

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