8

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

详细地说,考虑一下:公司可能有多名员工。通常这种情况可能会被设计为两个独立的资源,公司和员工,其中员工将是公司的子资源。

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

使用这种 URI 设计,公司表示应该包括到其员工的链接,但 XML 表示可能不包括员工本身。

因此,什么时候通过父项呈现子项才有意义?是否存在通过其父项呈现子项的情况。我的意思是根本没有子项目的 URI。只能通过父资源访问它们。

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

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

4

1 回答 1

8

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

但是,如果一个资源可以独立存在,并且您想要独立于任何其他资源来操作资源,那么它应该有自己的 URI。这样,您可以 POST 或 PUT 到该资源,而不会影响其他相关资源,也不必将它们复制回服务器。如果您必须从父项中操作所有内容,请考虑如果一个人执行 GET,修改一个子项,然后在更改该子项的情况下对整个事情执行 PUT 会发生什么;如果其他人同时更改了其中一个怎么办?然后你需要添加锁和事务语义,这会破坏 REST 的整个无状态性。

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

是的,拥有不止一种访问资源的方法是非常好的。你可以把它想象成一个博客;您可以在主页、存档页面或通过其永久链接获取故事。

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

  1. 锁定。一个客户端告诉服务器“我想要锁定整个数据集”,获取它想要修改的数据,修改数据,将其发送回服务器,然后解锁。
  2. 乐观并发:客户端下载数据集,该数据集标有某种修订标签,服务器每次获取新数据时都会更改该标签。客户端对其进行修改,并将其发送回服务器。如果同时修改了集合中的任何其他数据,则修订标签将没有数据,服务器将响应“对不起,您的数据已过期,请重试”。

这些各有优缺点。锁定的问题在于它是有状态的,因此不太适合 REST 架构。如果客户端程序在拥有锁时崩溃或以其他方式死亡,那么除非您有某种锁超时,否则该数据将被永久锁定,这可能会变得很棘手。如果客户端正在执行某种涉及多个锁的花哨事务,锁定也可能导致死锁。

乐观并发的问题在于,如果数据集负载很高,并且有很多客户端同时更改它,那么给定客户端可能需要多次尝试才能发布其数据;事实上,一个缓慢的客户端最终可能会完全中断发布更新,因为其他客户端不断地更改数据,这意味着缓慢的客户端更改总是失败。

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

于 2009-03-31T14:46:50.693 回答