REST数组操作最佳实践

时间:2014-06-03 09:23:16

标签: web-services api http rest

我可以通过REST完全访问foo资源:

{
  "name": "foo",
  "tags": [
    "tag01",
    "tag02",
    "tag03"
  ]
}

我想删除tag01数组中的tags

通常我会GET \fooPUT \foo没有tag01。 在这种情况下,这个对象很小,所以没关系。

但是让我们假设它要大得多。对于这种情况,我不想下载和上传这些数据。经过一些谷歌研究后,我发现了http PATCH。我看起来就像我需要的那样。

我的PATCH方式请求现在是

PATCH /foo/tags?op={add|delete}

要删除,我会使用:

PATCH /foo/tags?op=delete

有了这些数据:

{
  "value": "tag01"
}

现在有两个人认为我不喜欢:

  • 查询字段op - 是否有rfc或smth中描述的一些晦涩的名字。像这样
  • 请求数据中的
  • 成员value - 这也是自由选择的名称

对我来说看起来不正确。

还有其他方法可以通过REST操作数组吗?

是否有一些名称约定以PATCH方式执行?

2 个答案:

答案 0 :(得分:2)

PATCH的有效负载应包含"instructions describing how a resource currently residing on the origin server should be modified to produce a new version"。所有信息都应该在有效负载中传递,而不是在query-params中传递。

例如,您可以发送:

PATCH /foo

[
  { 
    "op": "remove",
    "path": "/tags/0" 
  }
]

路径/tags/0指向数组的第一个元素。其余的元素应该向左移动。

有关详细信息,请参阅JSON Patch draft

答案 1 :(得分:0)

  

还有其他方法可以通过REST操作数组吗?

是的,因为它不正确。通过REST,您可以将URL映射到资源(而不是操作),并使用HTTP方法和发送表示来操作资源。在URL或表示中使用op:remove是错误的。

  

是否有一些名称约定以PATCH方式执行?

没有REST命名约定。 REST结构与URI结构无关,因为它们遵循带语义注释的超链接。

如果你需要一个op:remove或类似的地方,那么它表明你的URI - 资源映射不好。您可能需要定义新资源或重新考虑资源结构。

我会将您想要的内容描述为批量创建和批量删除。您可以使用以下内容对此案例进行建模:

  • POST /collection [{},{},...] -> 201
  • DELETE /collection?filter="..." -> 204

要从集合中删除某些内容,您需要一个资源标识符URI。在这种情况下,它可以包含数组中的标记名称或索引(如果已订购)。

  • /foo/tags/tag01
  • /foo/tags/0

取决于你,但我会使用标签名称。

之后很简单:

  • POST /foo/tags ["a","b","c"]
  • DELETE /foor/tags?name="a,b,c"

因此,PATCH不是您正在寻找的方法,因为您正在创建和删除资源而不是替换它们。