REST:各个资源之间的关系

时间:2015-01-16 14:41:30

标签: rest standards relation hateoas

有人可以告诉我如何“RESTful”创建两个独立资源之间的关系吗? 我已经找到了几种方法,但我想坚持标准 我将列举几个例子来向你们展示我已经想到的东西 示例将包含一个必须链接到类别资源的帖子资源。

注意:所有示例都假设两个资源都已存在。

Ex 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

{}

那么删除这两种资源之间关系的最佳方法是什么?

“解决方案”
由于不再支持LINK和UNLINK,最好的解决方案imo(帽子提示@Bramus)将是PATCH示例。

因此,要创建一个链接,您可以调用:

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": ""
        }
    }
}

2 个答案:

答案 0 :(得分:1)

要将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表单做的事情:多个类别的多个复选框(结果是一个发布的数组)或下拉列表(结果是一个被发布的单个值)。

在旁注中,我没有将类别视为链接,而是作为子实体/子资源:

  • 子实体表示两个(主要是不同类型的)实体之间的关系。
  • 链接主要用于导航(nextprevparentme,...)

在PATCH中使用链接键与此意识形态不兼容。

答案 1 :(得分:0)

您已经接受了与您尝试使用PATCH相关的答案,但我想提出一个替代解决方案。我从非常简单的事情开始。为您的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"},
]

这很简单。客户端必须知道更少的信息才能执行将帖子添加到类别的用例。他们永远不必存储URL并知道将它们放在某个模板中的位置。

或者,您可以使用名称字段来指示帖子是否已成为会员。类似的东西:

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"},
]

从这里你可能会发现你有很多类别,每个类别都有一个链接可能很麻烦。答案是从您的帖子资源链接的中间资源。称之为类别后管理。通过x:post-category-management之类的关系从你的帖子链接到它。此资源允许分类分类,模糊搜索类别,某种方式删除所有类别,提供建议的类别。

{
  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 Architecture对Web应用程序进行映像,以及如果我没有javascript和表单控件,我希望它具有哪些类型的链接。由于假想的应用程序变得更加复杂,很明显每个帖子都需要一个类别管理页面。一个html页面ISA资源。

一旦我做到了,我就会开始支持一些更高级的东西。就像发送到应用类别URL的DELETE谓词一样,可以从帖子中删除它们。对我而言即使帖子属于类别,我也可以想到帖子中的类别。在实体关系图中,它实际上是您要删除的链接,DELETE将与该链接的URL一起发送,而不是实际类别。

也许那时我支持真正的PATCH请求(请求实体是像jsonpatch这样的补丁请求),以允许非常高级的客户端行为。