【问题标题】:Should a RESTful API return 400 or 404 when passed an invalid id传递无效 id 时,RESTful API 是否应返回 400 或 404
【发布时间】:2021-03-27 15:48:54
【问题描述】:

在构建 RESTful API 并且用户提供不存在的资源的 id 时,您应该返回 404 Not Found 还是 400 Bad Request

例如:

https://api.domain.com/v1/resource/foobar

foobar 不存在的地方。

【问题讨论】:

  • 在设计 api 时,自我记录是很重要的,因此当出现错误时,提供的 api 引导消费者纠正课程非常重要。抛出 404 首先是错误的文档,但也具有误导性。同样重要的是要注意 URL、HEADERS、BODY 都是请求的一部分,如果其中任何一个格式不正确,那么我会更喜欢 api 提供者返回明确的响应,这样我就可以正确。此外,我更喜欢格式良好的 req 进入我的内部应用程序甚至数据存储以避免不必要的意外。
  • 使用 404 并关注datatracker.ietf.org/doc/html/rfc7231#section-6.5.1 :“响应头字段允许服务器传递有关响应的附加信息,而不是放置在状态行中的信息。这些头字段提供有关服务器的信息,关于进一步访问目标资源,或关于相关资源。”

标签: rest


【解决方案1】:

如果资源不存在,我将返回 404(意味着 url 路径错误),并且仅当使用某些无效数据 (@PathParam) 进行其余调用时,我才会返回 400,例如
https://api.domain.com/v1/profile/test@email :这里我试图获取电子邮件 ID 的配置文件,但电子邮件本身是错误的,所以我将返回 400。
https://api.domain.com/v1/profile1111/test@email.com 将返回 404,因为 url 路径无效。

【讨论】:

  • 在这种情况下为什么要验证电子邮件?
  • 这个答案不正确。根据tools.ietf.org/html/rfc2616#section-10.4.5:10.4.1 400 Bad Request 由于语法错误,服务器无法理解请求。客户端不应该在没有修改的情况下重复请求。 10.4.5 404 Not Found 服务器没有找到任何匹配请求 URI 的东西。没有说明这种情况是暂时的还是永久性的。所以第一个例子应该返回 404 和第二个 400。
  • 要添加到@Przemo:IMO,如果您确实验证了电子邮件,那么第一个示例也应该返回 400,但如果电子邮件格式正常并且此电子邮件的记录不存在,然后返回 404。
  • 我不赞成的解释:给定标识符的资源存在,然后应返回 GET 请求而无需对标识符进行语法验证(通常是 HTTP 200 OK)。或者不存在,则返回404。您可以在处理 HTTP PUT 时对标识符进行此类验证。将其包含在 GET 中是错误的方法。
  • 如果你想完全遵循 REST-idea 可能是“不正确的”(这是可以理解的)。但是你有一个问题,你的 API 的客户端现在有办法区分这两种情况(URL 本身是错误的,还是他只是提交了一个无效的路径参数?)所以即使你在技术上是正确的 @Przemo 我认为你为了清楚起见,可以提出一个强有力的理由来偏离“正确”的方式 - 所以发送 400 以明确提供的参数有问题,而 url 本身是正确的
【解决方案2】:

应该是 404(未找到)。如果由于语法错误而无法满足请求,则使用 400,但是对于您的情况,语法是正确的,但是没有资源 foobar。

如果用户使用不存在的 API,您可以使用 400,如下所示:

https://api.domain.com/v1/nonexistAPI/xyz/xyz

您也可以参考这个REST API Design Blog,它告诉您如何设计您的 REST 错误代码。

【讨论】:

  • 那我就分不清是路线错了还是没找到物品。他们两个都会给我 404 ??
  • @Wahid Bitar:通常你会收到一个 OpenAPI 规范,它会告诉你可用的路线。使用它,您可以根据规范断言您的路线是正确的,并且您可以为此编写测试。
  • @Rudy:您使用“nonexistAPI”的示例也应该返回 HTTP 404,原因与您在答案的第二句中解释的原因相同:-) 即它是一个语法上有效的 HTTP 请求。
【解决方案3】:

404 Not Found 是我认为的正确答案,400 更多的是关于请求的主体而不是资源标识符,因此例如您可以通过验证错误发送它。

【讨论】:

  • IMO,例如,如果希望将 GUID 作为资源标识符,但方法中到达的字符串与 GUID 格式不对应,则应返回 HTTP 400 Bad Request。
  • @AlexDEV.pro 如果你有一个永远不会改变的严格 GUID 格式,我认为你是对的。
【解决方案4】:

这是一个有效的请求吗?资源的id可以存在吗?它是否被格式化为正确的 id?它在语法上正确吗?等等。如果是这样,那么您可以使用404 Not Found。否则400 Bad Request更合适。

【讨论】:

    【解决方案5】:

    根据 RFC (https://www.rfc-editor.org/rfc/rfc2616#section-10.4) API 应在以下情况下返回 404

    "服务器没有找到任何匹配 Request-URI",

    这是你的例子。

    400 表示资源被找到,但请求本身格式错误。

    例如: 一世。 https://api.domain.com/v1/resource/foobar

    foobar 不存在的地方应该返回 404

    二。 https://api.domain.com/v1/resource/foobar 如果 foobar 确实存在,但请求是错误的(例如{age:"NOTANINTEGER"}string 而不是 int),它应该返回 400。

    希望我能帮上忙。

    【讨论】:

      【解决方案6】:

      404 将是一种更常见的做法。它为Resource Not Found。在您的情况下,找不到特定的 URL。

      400 一般用于Bad Request。您可以将这个用于任何错误的请求。例如。 MissingRequiredQueryParameterInvalidInput

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-15
        • 2015-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多