REST:各个资源之间的关系
REST: Relations between individual resources
谁能告诉我如何 "RESTfully" 在两个单独的资源之间创建关系?
我想出了几种方法,但我想坚持标准。
我会列出几个例子来向你们展示我已经想到的东西。
示例将有一个 post 资源,必须 linked 到类别资源。
注意:所有示例都假定这两个资源已经存在。
示例 1:
PATCH /post/1 HTTP/1.1
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"post": {
"links": {
"category": "2"
}
}
}
示例 2:
POST /post/1/category/2 HTTP/1.1
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{}
示例 3:
POST /relations?post=id&category=id
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{}
删除这两个资源之间关系的最佳方法是什么?
"Solution":
由于不再支持 LINK 和 UNLINK,最佳解决方案 imo(帽子提示@Bramus)将是 PATCH 示例。
因此,要创建一个 link,您可以调用:
PATCH /post/1 HTTP/1.1
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"post": {
"links": {
"category": "2"
}
}
}
并删除它:
PATCH /post/1 HTTP/1.1
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"post": {
"links": {
"category": ""
}
}
}
要将 Post
放入 Category
我会使用一个简单的 PATCH
将所有这些 categories
作为数组传递(如果可以选择多个类别),或单个 category
键值对。
多个类别:
PATCH /post/1 HTTP/1.1
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"categories": [2, 3]
}
单个类别:
PATCH /post/1 HTTP/1.1
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"category": 2
}
它类似于您的第一个示例,但它在类别中作为数组/单个值传递时略有不同。我更喜欢这种方法,因为它模仿了通过普通 HTML 表单所做的事情:多个类别的多个复选框(结果是一个被发布的数组)或一个下拉列表(结果是被发布的单个值)。
在旁注中,我没有将类别视为 link,而是 sub-entity/sub-resource:
- 子实体表示两个 (主要是不同类型的) 实体之间的关系。
- 链接主要用于导航(
next
、prev
、parent
、me
、...)
在您的 PATCH 中使用 links 密钥与此意识形态不兼容。
您已经接受了与您使用 PATCH 的尝试相关的答案,但我想提出一个替代解决方案。我将从非常简单的事情开始。将一个新的 link 添加到您的 Post 资源类型中,用于它可以放入的每个类别。
在 HAL 中它看起来像这样:
x:category-add : [
{ "href" : "url/to/add/post/x/to/category/1", title : "Add Category 1"},
{ "href" : "url/to/add/post/x/to/category/2", title : "Add Category 2"},
{ "href" : "url/to/add/post/x/to/category/3", title : "Add Category 3"},
{ "href" : "url/to/add/post/x/to/category/4", title : "Add Category 4"},
]
那就太简单了。客户端需要知道的信息要少得多才能执行您将 post 添加到类别的用例。他们永远不必存储 URLs 并且知道将它们放在某个模板中的什么地方。
或者,您可以使用名称字段来指示 post 是否已经是成员。类似于:
x:category : [
{ "href" : "url/to/add/post/x/to/category/1", name : "add", title : "Add Category 1"},
{ "href" : "url/to/remove/post/x/to/category/2", name : "remove", title : "Remove Category 2"},
{ "href" : "url/to/add/post/x/to/category/3", name : "add", title : "Add Category 3"},
{ "href" : "url/to/remove/post/x/to/category/4", name : "remove", title : "Remove Category 4"},
]
从这里您可能会发现类别太多,每个类别都有一个 link 可能很麻烦。答案是从您的 post 资源中 link 编辑的中间资源。称之为 post-类别管理。 Link 通过 x:post-category-management 这样的关系从您的 Post 发送给它。让这个资源允许通过类别分页、模糊搜索类别、某种删除所有类别的方法、提供建议的类别。
{
x:category-suggested : [
{ href : "path/to/add/suggeted/category/Z", title : "Category Z"}
],
x:category-available : [
{ "href" : "url/to/add/post/x/to/category/1", title : "Add Category 1"},
],
next : { href : "url/to/next/available/categories" },
x:category-search : { href : "url/to/search/for/categories/for/post/x{?term}", templated : true}
}
这对我来说似乎简单多了。帮助我得到她的是使用 RESTful 体系结构对 Web 应用程序进行成像,以及如果我没有 javascript 和表单控件,我希望它具有哪些类型的 link。随着想象中的应用程序变得越来越复杂,很明显每个 post 都需要一个类别管理页面。 html 页 ISA 资源。
一旦开始,我就会开始支持一些更高级的东西。就像发送到应用类别 URL 的 DELETE 动词一样,将它们从 post 中删除。对我来说,即使 post 属于类别,我也可以认为类别属于 post。在实体关系图中,它是您实际要删除的 link,并且 DELETE 将与 link 的 URL 一起发送,而不是实际类别。
也许那时我会支持真正的 PATCH 请求(其中请求实体是像 jsonpatch 这样的补丁请求)以允许非常高级的客户端行为。
谁能告诉我如何 "RESTfully" 在两个单独的资源之间创建关系?
我想出了几种方法,但我想坚持标准。
我会列出几个例子来向你们展示我已经想到的东西。
示例将有一个 post 资源,必须 linked 到类别资源。
注意:所有示例都假定这两个资源已经存在。
示例 1:
PATCH /post/1 HTTP/1.1
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"post": {
"links": {
"category": "2"
}
}
}
示例 2:
POST /post/1/category/2 HTTP/1.1
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{}
示例 3:
POST /relations?post=id&category=id
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{}
删除这两个资源之间关系的最佳方法是什么?
"Solution":
由于不再支持 LINK 和 UNLINK,最佳解决方案 imo(帽子提示@Bramus)将是 PATCH 示例。
因此,要创建一个 link,您可以调用:
PATCH /post/1 HTTP/1.1
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"post": {
"links": {
"category": "2"
}
}
}
并删除它:
PATCH /post/1 HTTP/1.1
Host: api-host
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"post": {
"links": {
"category": ""
}
}
}
要将 Post
放入 Category
我会使用一个简单的 PATCH
将所有这些 categories
作为数组传递(如果可以选择多个类别),或单个 category
键值对。
多个类别:
PATCH /post/1 HTTP/1.1 Host: api-host Accept: application/json Content-Type: application/json Cache-Control: no-cache { "categories": [2, 3] }
单个类别:
PATCH /post/1 HTTP/1.1 Host: api-host Accept: application/json Content-Type: application/json Cache-Control: no-cache { "category": 2 }
它类似于您的第一个示例,但它在类别中作为数组/单个值传递时略有不同。我更喜欢这种方法,因为它模仿了通过普通 HTML 表单所做的事情:多个类别的多个复选框(结果是一个被发布的数组)或一个下拉列表(结果是被发布的单个值)。
在旁注中,我没有将类别视为 link,而是 sub-entity/sub-resource:
- 子实体表示两个 (主要是不同类型的) 实体之间的关系。
- 链接主要用于导航(
next
、prev
、parent
、me
、...)
在您的 PATCH 中使用 links 密钥与此意识形态不兼容。
您已经接受了与您使用 PATCH 的尝试相关的答案,但我想提出一个替代解决方案。我将从非常简单的事情开始。将一个新的 link 添加到您的 Post 资源类型中,用于它可以放入的每个类别。
在 HAL 中它看起来像这样:
x:category-add : [
{ "href" : "url/to/add/post/x/to/category/1", title : "Add Category 1"},
{ "href" : "url/to/add/post/x/to/category/2", title : "Add Category 2"},
{ "href" : "url/to/add/post/x/to/category/3", title : "Add Category 3"},
{ "href" : "url/to/add/post/x/to/category/4", title : "Add Category 4"},
]
那就太简单了。客户端需要知道的信息要少得多才能执行您将 post 添加到类别的用例。他们永远不必存储 URLs 并且知道将它们放在某个模板中的什么地方。
或者,您可以使用名称字段来指示 post 是否已经是成员。类似于:
x:category : [
{ "href" : "url/to/add/post/x/to/category/1", name : "add", title : "Add Category 1"},
{ "href" : "url/to/remove/post/x/to/category/2", name : "remove", title : "Remove Category 2"},
{ "href" : "url/to/add/post/x/to/category/3", name : "add", title : "Add Category 3"},
{ "href" : "url/to/remove/post/x/to/category/4", name : "remove", title : "Remove Category 4"},
]
从这里您可能会发现类别太多,每个类别都有一个 link 可能很麻烦。答案是从您的 post 资源中 link 编辑的中间资源。称之为 post-类别管理。 Link 通过 x:post-category-management 这样的关系从您的 Post 发送给它。让这个资源允许通过类别分页、模糊搜索类别、某种删除所有类别的方法、提供建议的类别。
{
x:category-suggested : [
{ href : "path/to/add/suggeted/category/Z", title : "Category Z"}
],
x:category-available : [
{ "href" : "url/to/add/post/x/to/category/1", title : "Add Category 1"},
],
next : { href : "url/to/next/available/categories" },
x:category-search : { href : "url/to/search/for/categories/for/post/x{?term}", templated : true}
}
这对我来说似乎简单多了。帮助我得到她的是使用 RESTful 体系结构对 Web 应用程序进行成像,以及如果我没有 javascript 和表单控件,我希望它具有哪些类型的 link。随着想象中的应用程序变得越来越复杂,很明显每个 post 都需要一个类别管理页面。 html 页 ISA 资源。
一旦开始,我就会开始支持一些更高级的东西。就像发送到应用类别 URL 的 DELETE 动词一样,将它们从 post 中删除。对我来说,即使 post 属于类别,我也可以认为类别属于 post。在实体关系图中,它是您实际要删除的 link,并且 DELETE 将与 link 的 URL 一起发送,而不是实际类别。
也许那时我会支持真正的 PATCH 请求(其中请求实体是像 jsonpatch 这样的补丁请求)以允许非常高级的客户端行为。