找不到时如何处理 Web API(“REST”)中的嵌套资源?

Tom*_*son 5 rest web asp.net-web-api

假设我有一个资源,Person而我有一个嵌套的资源SomeResource。在以下场景中应该返回哪个状态代码以及为什么?

/Person/1/SomeResource (SomeResource does not exist)
/Person/1/SomeResource (Person does not exist)
Run Code Online (Sandbox Code Playgroud)

我认为 404 应该在两种情况下都使用,但不是每个人都同意,我想知道为什么。您可能会争辩说,这Person是基础资源,SomeResource只是该资源的“属性”,SomeResource因此在第一种情况下应该不返回任何内容,但在第二种情况下返回 404的请求。我认为这可能是一种选择,但我仍然更喜欢 404。我完全不喜欢的另一种情况是返回 500 并带有错误描述,这也是我在讨论中听到的另一种选择,但这迫使消费者针对我不喜欢的异常进行编程。500 对我来说意味着出了点问题,你真的无能为力。

问题是,争论是你不知道为什么你得到了 404,如果你得到了它,是因为Person不存在还是因为SomeResource不存在。

更新 1: 也许我应该突破SomeResource到一个单独的资源,如

/SomeResource/1
Run Code Online (Sandbox Code Playgroud)

它返回类似 的响应{data: {the data}, person: {person data}},如果两者都丢失,则仅返回 404,但如果数据丢失,则返回 200 并带有空数据。

更新 2: 我想我想出了要使用哪个状态代码,当这个人不存在时它是 400,因为我当时认为它是一个你不应该做的请求,也就是说,一个错误的请求。当SomeResource缺少时,我会选择 404,因为Person确实存在但缺少嵌套资源。

Six*_*aez 1

记住给定的 URI 旨在识别单个“资源”可能会有所帮助。从语义上讲,URI 结构不支持“嵌套”资源的概念。看来您有两种资源:Person&SomeResource在您的场景中,其中SomeResource与 存在某种关系Person。您可以尝试使用这样的结构来表示这种关系:

GET /person/1

{
    name: "Some Value",
    someResource: {
        "Href": "http://yourSite.com/someresource/123",
        "Title": "Get some resource for this specific person"
    },

    // other key/value pairs as appropriate...
}
Run Code Online (Sandbox Code Playgroud)

这样您就不会超载具有应用程序特定含义的 400 和 404。如果客户端收到有效的 Person 结果,它将简单地调用SomeResourcehref 并根据SomeResource 123现有情况接收或不接收适当的 404。如果PersonURI 不存在,调用它会适当地返回 404,因为它不存在。