gpt4 book ai didi

api - REST 中数据的树结构 - URL 总是从根开始?

转载 作者:行者123 更新时间:2023-12-04 02:55:41 25 4
gpt4 key购买 nike

问题
当数据具有父/子/孙实体的树结构时,我们经常复制 URL 中的信息,指定父 ID,即使这不是必需的。在这种情况下设计 RESTful API 的最佳方法是什么?可以缩短 URL 并省略父 ID 吗?

例子
树如下: 最顶层的实体是产品。每个产品都有 0-N 条评论。每条评论可以附加 0-M 条评论。理论上,这棵树可以有任意深度。
简单的 RESTful API 看起来像这样(假设只有 GET 端点):

/products ... list of products
/products/123 ... specific product 123
/products/123/reviews ... list of reviews for product '123'
/products/123/reviews/abc ... specific review 'abc'
/products/123/reviews/abc/comments ... list comments for review 'abc'
等等,等一下……我写的最后两个标签没有提及产品“123”。是的,评论“abc”属于该产品,但作为人类,我不需要知道这一点。如果评论 ID 'abc' 在所有评论中是唯一的,那么计算机也是如此。
因此,例如,当我们发送更新 (PATCH) 请求以审查“abc”时,我们不需要知道直到树根(产品)的父对象的整个层次结构,例如它在此属于产品“123”案件。当然,我们假设每个对象在该实体的所有对象中都有一个唯一的 ID——但这是一种自然行为,例如在 RDB 中,很多人(好吧,他们的 API)都处于这种情况。

问题
  • 如果“子实体”的 ID 在该类型的所有实体中是唯一的,那么设计这样的 API 是最佳实践吗?
    /reviews/abc ... specific review 'abc'
    /reviews/abc/comments ... list comments for review 'abc'
    /comments/xyz ... specific comment 'xyz'
  • 如果对 (1) 的回答是肯定的,那么像这样的端点也应该有效吗?为什么?为什么不?
    /products/123/reviews/abc/comments/xyz ... specific comment 'xyz'
  • 如果允许(甚至首选)短 URL,那么这不是有点不一致吗?
    /products/123/reviews ... list reviews for product '123'
    /reviews/abc ... specific review 'abc'
    /reviews ... what should be here? all reviews?
  • 最佳答案

  • 是的。
  • 取决于 - 我不会推荐它,但如果你找到了它的用例,为什么不呢?
  • 我没有看到不一致 - 是的,在这种情况下 /reviews应该是系统中所有评论的列表,但如果这对您的应用程序没有意义,那么 /reviews只能产生 404,一切都很好。


  • 理想情况下,URL 的设计应该与 REST API 的其余部分分离。这意味着,就您的 URL 唯一标识您的资源而言,它们(从纯理论的角度来看)是“精心设计的”。

    但是 API 是一个接口(interface),它应该被如此对待。 API 是由机器使用的,而机器是由人编写的,所以实际上设计很重要。这与在您的博客上拥有漂亮 URL 的原因相同 - 没有技术原因,但是如果用户想要阅读、分享、记住或理解您的 URL(您可能会说 Google 搜索关键字),它会改善用户的体验在 URL 中,所以这是一个技术原因,但不,它不是 - Google 的机器人只是您的用户之一 - 网站消费者 - 机器人的优化就像您的用户的任何其他优化一样,因此它是界面设计)。

    如果 URL 的设计很重要(出于任何原因),那么在我看来,最好的方法是让它们保持简单。尽可能简单。您的观察非常正确 - 您不需要模仿资源的层次结构或在数据库中存储数据的方式。最终它只会妨碍你和想要使用你的 API 的人。

    如果资源在集合中由 ID 唯一标识,则只需设计您的 URL /collection/{id} .看看 Facebook 是怎么做的——它的大部分 API 都是这样做的。他们的 URL 结构非常扁平。

    甚至不需要 /collection用于列出所有现有对象的资源。您只能从有意义的地方链接它们,例如 /products/123/reviews ,您可以在其中列出指向 /reviews/{id} 的链接.

    为什么我认为复杂的 URL 不好?

    资源之间的关系是图形,不能将图形放到 URL 中

    无缘无故地将其他 ID 和层次结构放入 URL 会使事情变得更加复杂。通常,API 中的层次结构并不那么简单——资源之间的关系通常是非常复杂的图,而不是简单的树。因此,不要将资源之间的链接放入您的 URL 中 - 有更好的地方(超媒体格式、链接标题或至少 linking by ID references )可以放置有关关系的信息,并且这些信息不仅限于像 URL 这样的一个字符串,因此使用它们你可以更好地定义关系。

    你通过请求太多参数来折磨你的消费者

    通过要求消费者在 URL 中提供更多信息,您可以迫使他记住所有这些上下文和所有这些 ID,或者提前知道这些值。您需要更多(不必要的)输入,但实际上,消费者没有理由记住产品 ID 只是为了查看其评论之一。

    可进化性

    如果您的 URL 没有很好地解耦,您应该真正考虑如果数据结构随时间发生变化会发生什么。使用简单的 URL,什么都不会发生。对于复杂的 URL,每次更改 API 资源的相关方式时,您还需要更改 URL,以便它们跟上您的结构。众所周知,更改 URL 很困难——无论我们是在谈论 Web 还是 API。超媒体以某种方式解决了这个问题,但即使没有超媒体,您也可以做的很少,以保持您的 URL 轻巧且易于更改。

    你的设计可能是这样的
  • /products/{id} - 特定产品,链接到端点及其评论列表
  • /products/{id}/reviews - 列出产品评论端点的链接
  • /reviews/{id} - 具体评论,应该链接到评论过的产品,它甚至可以链接到上面的列表,如果它对 API 消费者有用的话

  • 事实上,这些资源中的任何一个都可以链接到系统中的任何其他东西,如果它有用或者存在逻辑连接的话。一些链接系统(例如超媒体)使理解这些链接更容易,因为您可以指定 rel属性,告诉消费者链接指向的位置( self 指向自身, next 可以指向另一个页面,等等)。

    当然,一如既往,这取决于您的具体情况。但一般来说,我建议保持 URL 解耦和简单。此外,我不建议尝试在 URL 中镜像任何复杂的关系或层次结构。

    关于api - REST 中数据的树结构 - URL 总是从根开始?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22115013/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com