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/create 的角度来看,方法 3 很有趣,但在更新和删除方面有点麻烦。

我可以看到所有这些方法的优点和缺点,因此我正在向可能已经接近并解决过这个问题的人寻求更多指导。

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

4

2 回答 2

9

REST API必须是超媒体驱动的。请参阅超媒体作为应用程序状态引擎 (HATEOAS)约束。所以,不要在 URLPatterns 上浪费时间,因为它们不是 RESTful。URLPattern 暗示了客户端和服务器之间的紧密耦合;简单地说,客户端必须知道 URL 的样子并有能力构造它们。

为您的用例考虑这个 REST 设计:

文档的表示包含一个链接,客户端可以在其中发布评论或使用 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

于 2013-03-08T14:18:21.950 回答
0

方法 1 和 2 的组合看起来不错,正如您在方法 2 中所说,在没有文档上下文的情况下创建评论没有太大意义,因为两者之间存在父子关系,如果您删除一个文档,删除他的所有文档是可以接受的还可以评论,您可以使您的/comments/uri 成为只读资源,以避免在没有文档的情况下创建他。

正如 filip26 所说,rest apis 应该是超媒体驱动的,但这并不意味着 url 模式不重要,你可以拥有一个具有一个或多个 uri 的资源,如果你的资源有多个 uri 更容易让客户找到它们,缺点是这可能会令人困惑,因为某些客户端使用一个 uri 而不是另一个,因此您可以将规范 uri 用于资源,当客户端通过此规范 uri 访问资源时,您可以发送回 a 200 OK,当客户端请求其他 uri 之一时您可以连同规范的 uri 一起发回 303“另请参阅”。`

于 2013-05-26T08:55:22.230 回答