何时在RESTful资源表示中包含子项?

时间:2009-03-31 14:35:37

标签: xml rest structure nested

RESTful设计似乎提倡平面或浅层结构化表示(至少在资源表示为XML时)。资源表示应该只包含URI标识的资源。我想知道何时在父资源中提供资源的子资源是明智的吗?

详细说明,请考虑以下事项: 公司可能有多名员工。通常这种情况可能被设计为两个独立的资源,公司和员工,员工将成为公司的子资源。

/company/acme/
/company/acme/employees/
/company/acme/employee/john

使用此URI设计,公司表示应包含指向其员工的链接,但XML表示可能不包括emplyoyees本身。

因此,何时通过父母提出子项?是否存在通过其父项呈现子项 是明智的。我的意思是根本没有子项的URI。只能通过父资源访问它们。

<company>
<name>Acme</name>
 <employees>
  <employee>John</employee>
  <employee>Jack</employee>
 </employees>
</company>

仅提供一种访问资源的方法是明智的:如果父项公开其子项,那么子项也可以有明确的URI吗?那么,如果公司的XML包含公司的员工,那么提供/ company / acme / employees URI dispite是否有意义,您可以通过公司资源获得相同的信息?

1 个答案:

答案 0 :(得分:8)

如果子资源仅在其父资源的上下文中有意义,那么是的,它应该返回嵌套在其父资源中。例如,在HTML中,<li>元素本身作为子资源没有意义。

但是,如果资源可以独立存在,并且您希望独立于任何其他资源来操作资源,那么它应该具有自己的URI。这样,您可以POST或PUT到该资源,而不会影响其他相关资源,而无需将它们鹦鹉回到服务器。如果你不得不操纵父母的一切,想想如果一个人做GET会发生什么,修改一个子项,然后改变那个子项的整个事物的PUT;如果其他人在此期间改变了其中一个怎么办?然后你需要添加锁和事务语义,这会破坏REST的整个无状态。

至少对于GET请求,拥有某种形式的批量查询接口可能是一个好主意,通过该接口,客户端可以同时获得大量资源;必须为每个资源执行新的HTTP请求可能需要很长时间,因为这意味着每个GET通过网络进行新的往返。拥有批量更新功能也是有意义的。但是,如果您希望一次能够操作一个资源,则需要为该资源提供URI。

是的,拥有多种访问资源的方式完全没问题。你可以把它想象成一个博客;你可以在主页面上,或在档案页面上,或通过永久链接获取故事。

编辑:如果您想要进行批量更新而不会遇到让一个客户端向服务器提供陈旧数据的问题,那么您基本上有两个选择:

  1. Locking。一个客户端告诉服务器“我希望锁定这整组数据”,获取它想要修改的数据,修改数据,将数据发送回服务器并解锁。
  2. Optimistic concurrency:客户端下载数据集,该数据集标记有某种修订标记,服务器每次获取新数据时都会更改。客户端修改它,并将其发送回服务器。如果同时修改了集合中的任何其他数据,则修订标记将缺少数据,服务器将回复“抱歉,您的数据已过期,请重试。”
  3. 这些都有优点和缺陷。锁定的问题在于它是有状态的,因此不能很好地适应REST架构。如果客户端程序在锁定时崩溃或死亡,那么该数据将永久锁定,除非您有某种锁定超时,这可能会变得棘手。如果客户端正在进行某种涉及多个锁的奇特事务,则锁定也可能导致死锁。

    乐观并发的问题在于,如果数据集上存在高负载,并且很多客户端一次更改它,则在给定客户端发布其数据之前可能需要许多次尝试;事实上,一个缓慢的客户端最终可能会完全切断发布更新,因为其他客户端不断更改数据的方式意味着慢速客户端更改总是失败。

    您需要自己决定哪些选项适合您。更改单个资源时会出现这些问题(一个更新可能会破坏另一个资源),但是当您将资源聚合到批量接口时,它们会更频繁地出现。这就是为什么我建议有两个接口,如果你要聚合资源;可以单独访问资源的一个,以及可以一次读取和写入许多资源的可选批量接口。