REST API 设计:链接资源

7

假设我有两个顶级资源FooBar。现在Foo需要链接到一些Bar。在Java类中,这可能看起来像这样:

public class Foo {

  Set<Bar> bars;
}

public class Bar { … }

我希望你能帮我将Foo的XML表示形式改成这样:

GET /foos/1

<foo>
  …
  <atom:link rel="self" href="/foos/1" />
  <atom:link rel="bars" href="/foos/1/bars" />
</foo>

因此,我将所有分配给FooBar作为嵌套资源公开。这意味着Bar资源具有独立的生命周期(组合而非聚合)。然后,嵌套的资源可能会公开所有链接的Bar,如下所示:

GET /foos/1/bars

<bars>
  <atom:link rel="bar" href="/foos/1/bars/1" />
  <atom:link rel="bar" href="/foos/1/bars/2" />
</bars>

另一种方法是提前将集合内联到<foo>元素中。但是我仍然有一些问题:虽然这使我可以通过触发对例如/foos/1/bars/1DELETE请求来很好地从Foo中删除一个Bar,但如何将一个Bar分配给一个Foo呢?假设客户端访问/bars得到:

GET /bars

<bars>
  <bar>
    …
    <atom:link rel="self" href="/bars/4711" />
  </bar>
</bars>

决定将/bars/1 分配到 /foo/1/bars。 我考虑使用POST 请求 /foo/1/bars,但不确定实际提交什么内容。例如下面的指向 Bar 资源的link元素?

POST /foos/1/bars

<atom:link href="/bars/4711" />

这似乎还可以,因为客户端不需要创建URL,同时我们仍然满足REST约束条件。但是,将链接POST到服务器感觉有点奇怪。是否有更好的解决方案呢?


1
我毫不犹豫地会POST一个链接来建立两个资源之间的关系。有些人认为你应该检索资源,然后将其POST以实现自描述,但我并不认为这是必要的。 - Darrel Miller
这也是我感觉到的,因为你 a) 创建了不必要的聊天气氛,b) 实际上并不需要在服务器端使用整个表示来创建链接。 - Oliver Drotbohm
1个回答

6

我认为这个问题应该从服务器理解的资源角度出发,而不是仅仅从XML表示角度来看(例如)GET请求响应时返回的内容。我的RESTful服务可以返回JSON或XML,也可能返回其他格式。

所以,我同意您的POST或PUT请求。

 /foos/{fooId}/bars

要么指定完整的酒吧列表,要么添加一些酒吧。

发布负载的格式可以是您使用的媒体类型的自然序列化形式。在我的情况下,它通常是一个JSON字符串,因此在我的服务实现中,我会反序列化并查看资源引用URL字符串数组。

如果您的

<atom:link href="/bars/4711" /> 

如果反序列化后能够漂亮地呈现,那么即使序列化形式有点“装饰性”,也不应该成为问题。

总结:按照你的(反)序列化器自然的方式去处理即可。


实际上,我认为这里实际的表示并不重要。如果我使用JSON,同样的问题也会出现。我只是选择在这里举例使用XML,因为有一个标准的“link”元素,而在JSON中我需要自己想出一些东西。无论如何,感谢您的回答! - Oliver Drotbohm
好的,你的情况中表示有“atom:link”这些词,我认为这是你担心的原因。像“/bars/4711”这样的唯一标识对我来说似乎很普遍 - 你必须要有一些标识,对吧? - djna
对的,这让我感觉有点奇怪的原因是,到目前为止,我只向客户端发送了服务器链接,以便让客户端浏览资源。从未有必要将链接POST回来,并被困在客户端需要想出URL的感觉中,从而违反了REST原则。但实际上它提前发现了,所以我应该没问题。 - Oliver Drotbohm
@OliverGierke(和djna):我同意这个想法。对于一般内容为JSON的“只是链接”内容,有什么关于“Content-Type”的想法/结论?使用application/json+href并带有一个主体{"href"="/bars/4711"}?可以找到许多(ATOM)基于XML的约定,但很难找到任何基于JSON的先前技术。 (通常使用HAL,因此最好与之匹配的内容) - Ruben Bartelink
有一个 text/uri-list 用于纯文本换行分隔的URI... http://www.fileformat.info/info/mimetype/text/uri-list/index.htm - Oliver Drotbohm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接