REST API 包含和排除子资源

REST API including and excluding of subresources

我正在尝试确定一种 RESTful 方法来根据特定请求随意包含和排除子资源。

例如,这可能是原始请求:

获取departments/321

200 (Ok)
{
    "id": "321",
    "name": "Sales",
    "building": "The Foundary"
    "subdepartments": [
       {
          "id": "123",
          "name": "Training"
       },
       {
          "id": "224",
          "name": "Book Sales"
       }
       ...
    ]
}

可能会有很多子部门。 GET departments 资源也将包括每个部门以及这些部门的每个子部门。大量数据。

这可以通过创建两个单独的资源来解决:

获取departments/321

200 (Ok)
{
    "id": "3",
    "name": "Sales",
    "building": "The Foundary"
}

GET departments/321/子部门

200 (Ok)
[
   {
      "id": "123",
      "name": "Training"
   },
   {
      "id": "224",
      "name": "Book Sales"
   }
   ...
]

但在某些情况下,客户端软件可能不希望发出多个请求(最有可能是出于性能考虑)。也许通过提供 include 过滤器:

GET departments/321?include=子部门

200 (Ok)
{
    "id": "321",
    "name": "Sales",
    "building": "The Foundary"
    "subdepartments": [
       {
          "id": "123",
          "name": "Training"
       },
       {
          "id": "224",
          "name": "Book Sales"
       }
       ...
    ]
}

或排除过滤器:

GET departments/321?exclude=子部门

200 (Ok)
{
    "id": "321",
    "name": "Sales",
    "building": "The Foundary"
}

虽然我们可能需要在子资源中包含一个 link 如果它被排除?

GET departments/321?exclude=子部门

200 (Ok)
{
    "id": "321",
    "name": "Sales",
    "building": "The Foundary"
    "subdepartments": {
        "href" : "api.com/departments/321/subresources"
    }
}

是否有可接受的RESTful方式来执行上述包含或排除子资源的操作?

我对添加这些参数没有任何问题,所以请继续使用它,最重要的部分是您管理 http 状态代码,响应具有良好的结构来读取数据(并且您有它!)

此外,如果您想以另一种方式查看,请使用 OData:Web API and OData

正确的 REST 服务必须使用超媒体 (links) 连接到相关资源。如果我们使用自定义媒体类型而不是 JSON Collection 或 AtomPub 之类的东西,第一次调用的响应将类似于

{
    "id": "321",
    "name": "Sales",
    "building": "The Foundary"
    "links": [
          { "rel": "subdepartments", "href": "departments/321/subdepartments", "method": "get" }
     ]
}

您可以调用 link 来为所有子部门获取具有 link 的资源。

{
    ...
    "links": [
      { "rel": "subdepartment", "href": "departments/321/subdepartments/1", "method": "get" },
      { "rel": "subdepartment", "href": "departments/321/subdepartments/2", "method": "get" }
    ]
}

它的工作方式几乎就像浏览网站并单击 links。

阅读 Roy Fielding 本人的博客 post: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

这种方法可能会出现明显的复杂性和性能问题。当服务器应用程序可以独立于客户端发展时,RESTful 服务确实有意义。否则,只需使用带有查询字符串参数的方法。

这听起来非常适合 http://jsonapi.org/ – 在构建您的 JSON 响应时 "your anti-bikeshedding weapon"。与实施您自己的临时模式相比,一开始阅读规范可能需要一些时间,但它确实值得。 该规范还包含一个 section about "compound documents" 部分,该部分还使用 include=… 参数通过一个请求获取多个 documents/resources。