REST API设计:资源集合之间的链接

10

我一直在思考定义具有相互依赖的资源集合的正确方法。

例如,让我们考虑“文档”和“评论”,它们可以通过以下URI独立访问:

/documents/{doc-uri}
/comments/{comment-id}

然而,我们通常希望获取与特定文档相关的评论集合。这就引出了一个设计问题,涉及如何构建这个集合。

我可以看到几个主要选项:

1.) 在文档 uri 后提供一个评论集合 uri

GET /documents/{doc-uri}/comments/

2.) 提供一个参数给评论集合,以选择文档

GET /comments/{comment-id}?related-doc={doc-uri}

3.) 使用内容协商通过 Accept 头请求相关的评论被返回。

// Get all the comments for a document
GET /documents/{doc-uri} Accept: application/vnd.comments+xml
// Create a new comment
POST /documents/{doc-uri} Content-Type: application/vnd.comment+xml <comment>...</comment>

方法1的优点在于自动将评论放置在文档的上下文中,这也很好地支持了使用POST/PUT创建、更新和删除评论。然而,它不提供对文档之外评论的全局访问。因此,如果我们想要在系统中搜索所有评论,我们需要使用方法#2。

方法2提供了与方法1许多相同的优点,但是在没有文档上下文的情况下创建评论是没有意义的,因为评论必须明确与文档相关联。

从GET和POST/创建的角度来看,方法3很有趣,但是更新和删除可能会有些复杂。

我可以看到这些方法的利弊,因此我正在寻找一些解决这个问题的指导。

我正在考虑同时使用方法1和方法2,这样我可以提供所需的所有功能,但我担心可能会过于复杂/重复功能。

2个回答

9
REST API必须是超媒体驱动的。请参考“应用状态的超媒体引擎”(HATEOAS)约束条件。因此,不要浪费时间在URLPattern上,因为它们不符合RESTful。URLPattern暗示客户端和服务器之间的紧密耦合;简单地说,客户端必须了解URL的外观,并有能力构建它们。
考虑针对您的用例设计这个REST API:
文档的表示包含一个链接,客户端可以使用该链接发表评论或使用GET获取文档上的所有评论。例如。
{
  ...
  "comments" : {
      "href": ".. url ..",
      "rel": ["create-new-comment", "list-comments"]
  }
}

一个客户端只需要获取这个URL并在该URL上执行GET或POST方法,而不需要知道URL的样子。

另请参阅此帖子:

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven


你的意思是超媒体,而不是超文本。这是REST的HATEOAS(http://en.wikipedia.org/wiki/HATEOAS)部分。 - jpbochi

0
方法1和方法2的组合看起来不错,正如您在方法2中所说,如果没有文档上下文,则创建注释没有太多意义,因为两者之间存在父子关系,如果删除一个文档,则可以删除所有评论,您可以使/comments/ uri成为只读资源,以避免在没有文档的情况下进行创建。
正如filip26所说,rest api应该是超媒体驱动的,但这并不意味着url模式不重要,您可以有一个uri或多个uri的资源,如果您的资源具有多个uri,则客户端更容易找到它们,缺点是可能会令人困惑,因为某些客户端使用一个uri而不是另一个uri,因此您可以为资源使用规范化uri,当客户端通过此规范化uri访问资源时,您可以发送200 OK,当客户端请求其他uri之一时,您可以发送303“请参阅”以及规范化uri。

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