RESTful重新排序嵌套对象

时间:2014-12-15 12:31:04

标签: rest http nested restful-url restful-architecture

我有一个支持两个对象的RESTful API,因此对象A包含嵌套对象B的有序列表:

Create object A               - POST  /a
Create object B and add to A  - POST  /a/<id>/b
Update object B in A          - PATCH /a/<id>/b/<id>

更新特定BA个对象的顺序的RESTful方法是什么?

选项1: PATCH /a/<id>,其中json内容替换A.Bs
A有一个嵌入式B列表,即A.Bs,因此您可以完整替换该列表,同时也可以更改订单。这依赖于客户端正确地重新提交整个列表。

选项2: PATCH /a/<id>,其中json内容替换A.B_order
添加单独的B ID列表,让客户端更新它。这与选项1类似,但不依赖于客户端重新提交所有对象。它确实需要服务器管理列表,在B创建时更新它,并验证更新包含列表顺序更新所需的所有B ID。

选项3: PATCH /a/<id>/b,其中json内容替换A.Bs
与选项1相同,但使用不同的URL

哪个最干净,更清晰? 还有其他选择吗?

3 个答案:

答案 0 :(得分:2)

我建议使用RFC 6902中定义的建议标准。具体而言,&#34;移动&#34;操作似乎是您正在寻找的。

答案 1 :(得分:0)

鉴于Foo有Bars,而Bars是资源(具有ID或链接),当您需要重新排序foo.bars时,我建议:

“ PUT / foos /:id / bars”在正文中带有ID或链接的数组。

但是,如果Bar不是资源(没有ID),则:

“ PATCH / foos /:id”,其中包含Foo主体,并在“ bars”属性中包含完整的Foo.bars新数组。

答案 2 :(得分:0)

我要问自己的问题是:“在这种情况下,'命令'是什么意思。”

B的特定实例之间没有顺序。它们都是独立的资源,并不是真正“了解”每个订单。

鉴于此,您实际上并不是在更改B资源。你要改变什么?

大概某处有B的集合。您对该集合执行GET的请求,以获得B的有序列表。您是在/a/<id>还是/a/<id>/b上获得该列表的??

无论排序列表在哪里,我都会执行更改订单的操作,因为订单是集合的“属性”。

因此,为了便于讨论,假设您的B集合生活在/a/<id>b上。那应该是什么格式?

好的,良好的REST服务将取代整个状态。因此,默认情况下,我将对该资源执行PUT请求,并完全替换整个内容。

如果您不喜欢这个想法,并且想使用PATCH仅更新集合的一部分(没有其他内容),我想我会选择其中之一:

  1. 使用标准格式,例如json-patch
  2. 使用您自己的语法来描述。

选项2的实现可能会简单得多,我还将保持格式尽可能简单。

如果使用类似HAL的格式,则集合可能是链接列表。在这种情况下,我将使用类似以下语法:

{
  "_links": {
     "item": [
        { "href": "/a/<id>/b/ordered-item-1" },
        { "href": "/a/<id>/b/ordered-item-2" }
      ]
  }
}

如果您没有超媒体风格的API,则可能使用id并强制客户端在URL中扩展id。在那种情况下,我想格式会像这样:

{
   "items": [ 1, 3, 5, 2]
}

在每种情况下,为此定义自己的媒体类型是一个好主意,因为PATCH的这种格式对您的api具有特殊的意义。例如:

application/vnd.jonathan.patch+json