我正在尝试确定一种RESTful方式,以便为特定请求包含和排除子资源。
例如,这可能是原始请求:
获取部门/ 321
200 (Ok)
{
"id": "321",
"name": "Sales",
"building": "The Foundary"
"subdepartments": [
{
"id": "123",
"name": "Training"
},
{
"id": "224",
"name": "Book Sales"
}
...
]
}
可能有一个很大的子部门列表。然后,GET departments
资源也将包括每个部门和每个部门'分部门。很多数据。
这可以通过创建两个独立的资源来解决:
获取部门/ 321
200 (Ok)
{
"id": "3",
"name": "Sales",
"building": "The Foundary"
}
获取部门/ 321 /子部门
200 (Ok)
[
{
"id": "123",
"name": "Training"
},
{
"id": "224",
"name": "Book Sales"
}
...
]
但有时客户端软件可能不愿意提出多个请求(出于性能原因)。也许通过提供include
过滤器:
获取部门/ 321?包含=子部门
200 (Ok)
{
"id": "321",
"name": "Sales",
"building": "The Foundary"
"subdepartments": [
{
"id": "123",
"name": "Training"
},
{
"id": "224",
"name": "Book Sales"
}
...
]
}
或排除过滤器:
获取部门/ 321?排除=子部门
200 (Ok)
{
"id": "321",
"name": "Sales",
"building": "The Foundary"
}
虽然如果排除了子资源,我们可能还需要包含子资源的链接吗?
获取部门/ 321?排除=子部门
200 (Ok)
{
"id": "321",
"name": "Sales",
"building": "The Foundary"
"subdepartments": {
"href" : "api.com/departments/321/subresources"
}
}
是否有可接受的REST执行上述方式,包括或排除子资源?
答案 0 :(得分:2)
添加这些参数我没有任何问题,所以继续使用它,最重要的部分是你管理http状态代码,响应有一个很好的结构来读取数据(你有它! )
另外,如果你想看到另一种方式,请使用OData:Web API and OData
答案 1 :(得分:1)
正确的REST服务必须使用超媒体(链接)连接到相关资源。如果我们使用自定义媒体类型而不是像JSON Collection或AtomPub那样,第一次调用的响应看起来像
{
"id": "321",
"name": "Sales",
"building": "The Foundary"
"links": [
{ "rel": "subdepartments", "href": "departments/321/subdepartments", "method": "get" }
]
}
您可以调用该链接以获取包含所有子部门链接的资源。
{
...
"links": [
{ "rel": "subdepartment", "href": "departments/321/subdepartments/1", "method": "get" },
{ "rel": "subdepartment", "href": "departments/321/subdepartments/2", "method": "get" }
]
}
它的工作方式几乎就像浏览网站并点击链接一样。
阅读Roy Fielding本人的博客文章: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
这种方法可能会出现明显的复杂性和性能问题。当服务器应用程序可以与客户端分开进化时,真正的RESTful服务才有意义。否则,只需使用查询字符串参数的方法。
答案 2 :(得分:1)
这听起来非常适合http://jsonapi.org/ - 在构建JSON响应时,它是“你的反自行车武器”。与实现您自己的ad-hoc架构相比,阅读规范可能最初需要一些时间,但实际上是值得的。
该规范还包含一个section about "compound documents"部分,该部分还使用include=…
参数通过一个请求获取多个文档/资源。