在RESTful APIs中,包含/嵌入与链接的区别

14

因此,RESTful API 的一般模式是返回一个带有嵌入链接的单个对象,您可以使用这些链接来检索相关对象。但有时为了方便,您想要一次性获取整个对象图。

例如,假设您有一个商店应用程序,包括客户订单退货。您想同时显示客户ID 12345的个人信息、所有订单和所有退货。(假设不总是在返回客户个人信息时返回订单和退货有很好的理由。)

纯粹的 RESTful 方法如下:

  1. GET /
    • 返回链接模板列表,其中包括一个用于查询客户的模板
  2. GET /customers/12345(基于来自 / 的链接模板)
    • 返回客户个人信息
    • 返回链接以获取此客户的订单和退货
  3. GET /orders?customerId=12345(从 /customers/12345 响应中获取)
    • 获取客户12345的订单
  4. GET /returns?customerId=12345(从 /customers/12345 响应中获取)
    • 获取客户12345的退货

但是,一旦您拥有了 customers URI,就可以通过一次查询将所有内容都返回。是否有关于这种方便查询的最佳实践,其中您想要转移某些或所有链接,而不是进行多个请求?我考虑的是:

GET /customers/12345?include=orders,returns

但如果有人已经在做这方面的事情,我宁愿不要凭空想象。

(顺便说一句,我没有建立商店,所以让我们不要争论这是否是模型的正确对象,或者你将如何深入到实际产品,或其他什么问题。)


更新后添加:HAL语言中,这些被称为“嵌入式资源”,但在所展示的示例中,似乎没有任何方法可以选择要嵌入哪些资源。我找到了一个博客文章建议使用embed作为查询参数来实现我上面描述的东西:

GET /ticket/12?embed=customer.name,assigned_user

这是一种标准或半标准的做法,还是只是某个博主想出来的东西?

1个回答

1

鉴于这些参数的语义必须为支持它们的每个链接关系进行文档化,并且这是您必须编写的内容,我不知道通过具有标准表达方式能获得任何收益。 URL结构更可能由服务器返回最容易或最明智的内容来驱动,而不是遵循任何特定的标准或最佳实践。

话虽如此,如果您正在寻找灵感,可以查看OData在$ expand parameter方面的处理方式,并从中建模您的链接关系。请记住,仍应清楚定义您的关系契约,否则客户端程序员可能会看到类似于OData的约定并错误地假定您的应用程序完全符合OData,并将像一个OData一样运行。


1
您提供的 $expand 参数链接已损坏。 - Jacob Wallace
1
损坏的链接应该被替换为查看此页面中的$expand部分。 - Leith
1
谢谢,Leith!已修复。 - Jonathan W

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