2012-01-11 76 views
6

假设我有两个顶级资源FooBar。现在Foo需要链接到一些Bar。在一个Java类,这可能是这个样子:REST API设计:链接资源

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> 

所以我几乎都暴露Bar分配Foo作为嵌套资源。这意味着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> 

Alteratively我可以内嵌在集合中的元素<foo>前期。不过,我仍然坚持一些问题:虽然这使我可以通过触发DELETE请求来很好地从Foo中删除Bar/foos/1/bars/1但是如何将一个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,但不确定要实际提交的内容。 A link元素指向Bar资源如下?

POST /foos/1/bars 

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

这似乎相当好为客户仍然不需要创建URL,我们仍然满足REST约束。但是,对于POST指向服务器的链接感觉有点奇怪。这种情况有更好的解决方案吗?

+1

我会毫不犹豫地发布一个链接来建立两个资源之间的关系。有些人认为你应该检索资源,然后POST自我描述,但我不相信这是必要的。 – 2012-01-11 12:20:51

+0

这就是我也觉得,因为你是a)创造不必要的健忘和b)实际上并不需要在服务器端实际创建链接的整个转发。 – 2012-01-11 19:59:32

回答

4

我认为这是根据服务器理解的资源而不是响应(例如)GET请求而流动的XML表示。我有RESTful服务返回JSON或XML,或者可能的其他表示。

所以我跟你张贴或PUTing同意

/foos/{fooId}/bars 

指定任一酒吧的完整列表,或者加一些吧。

张贴的有效负载的格式可以是任何您自己使用的媒体类型的自然序列化格式。在我的情况下,它通常是一个JSON字符串,所以在我的服务实现中会反序列化并看到一个resoruce引用URL字符串数组。

如果您

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

也deserialise很好的话,我没有看到一个问题,如果序列化形式是有点那个,观赏性。

摘要:对你的(de)序列化程序做一些自然的事情。

+0

其实我不认为这里的实际陈述很重要。如果我使用JSON,会出现同样的问题。我只是选择了XML作为示例,因为有一个标准的'link'元素,我不得不用JSON自己想出一些东西。不过谢谢你的回答! – 2012-01-11 11:24:51

+0

以及你的案例中的表述有atom:link这个词,我认为这是你关心的原因。像“/ bars/4711”这样的唯一标识对我来说似乎没有什么争议 - 你必须有一些ID,对吧? – djna 2012-01-11 12:58:52

+0

对,这可能让我觉得有点奇怪的原因是我只发送了从服务器到客户端的链接,只能让客户端导航资源。从来没有必要发布一个链接回来,并被客户不得不拿出URL并因此违反REST原则的感觉所困扰。但事实上它在前面发现了,所以我应该没问题。 – 2012-01-11 20:01:34