3

一个直截了当的问题:如果我正在构建一个无状态客户端,它在请求之间“更改页面”,我如何正确使用超媒体 API?

当然,关键点是客户端不应该构造 URL。例如,如果我们要获取某种类型的集合(比如说水果),每个集合条目都将具有一个 URL,以链接到 API 中的单个水果资源。伟大的。

[ { "name": "Apple", "url": ".../fruits/15" } ]

然而,在我的客户中,在展示水果列表后,我希望将列表链接到另一个包含水果详细信息的前端页面。这样的详细信息页面当然应该是可收藏的,等等。前端 URL 的精确结构是我意识到的,从哲学上讲,很少关注 - 但它对下面的问题具有实际意义。

<a href="?">Apple</a>

那么问题是,在加载水果详细信息页面时,没有当前上下文的客户端如何决定要获取的 API URL?

/my/frontend/stuff/fruits/{?}

现在是什么:o?

最初想到的一个解决方案是在集合响应中有一个“项目”URL 模板,并使用其中的命名参数来构造页面 URL。然后详细信息页面将查询 API 以恢复相同的“项目”URL 并植入它传递的参数。这似乎并不理想,但它确实实现了所需的解耦。

提前致谢。

4

2 回答 2

4

Web 浏览器是许多用户最熟悉的无状态客户端。您所要求的称为URI 模板,并受到各种超媒体格式的支持。例如,在 HTML 中:

<form action="/api/fruits" method="GET">
  <input type="number" name="id" value="1" min="1">
  <button type="submit">Get Fruit</button>
<form>

提交时当然会生成对 URI 的 GET 请求/api/fruits?id=1

其他超媒体格式(例如 HAL)允许在 URI 中的任何位置进行模板化,并且比 HTML 更适合 Web 应用程序。您需要查看您首选的超媒体表示格式支持的模板机制,或者切换到支持您需要的格式。

当然,在 HTML 中,由于模板不好,我们必须列出每个所需的 URI 并对长列表进行分页:

<a href="/api/fruits/1/">Apple</a>
<a href="/api/fruits/2/">Banana</a>
<a href="/api/fruits/3/">Citrus</a>
...
<a href="/api/fruits/?page=2" rel="next">Page 2</a>

不过老实说,如果用户要直接输入 ID,您可能也应该允许 HTML 和查询字符串参数。当第三方客户端开发人员针对您的 API 进行构建时,它将帮助他们,如果您需要与最终用户一起调试,它的可用性将有所帮助。只需将他们指向一个 URL 并询问“如果你去这里它有用吗?”

于 2013-07-13T21:07:53.743 回答
1

如果我正确理解了问题,则工作流程中有两个步骤:

第 1 步:客户端 – GET(/api/fruits/)

  • 返回:[{“name”:“Apple”,“Id”:1},{…}]

第 2 步:客户端 – GET(/api/fruits/1/)、GET(/api/fruits/2/)、……</p>

  • 返回每个水果的详细信息

客户端必须已经知道“根”URL-“/api/fruits/”才能在步骤 1 中获取列表。为了像在步骤 2 中那样获取单个水果的详细信息,客户端连接“根”URL - “/api/fruits/”和在步骤 1 中返回的“Id”。

不确定您是否熟悉流行的 javascript 框架Backbonejs。它的模型开箱即用地支持这一点。我相信大多数其他框架也应该支持这种类型的工作流。

您可以查看这些特定于骨干网的链接作为示例:

希望有帮助

于 2013-07-04T15:33:27.267 回答