81

对于我参与的一家 SaaS 初创公司,我正在构建一个 RESTful Web API 和几个使用它的不同平台上的客户端应用程序。我想我已经弄清楚了 API,但现在我正在求助于客户。正如我一直在阅读有关 REST 的内容,我发现 REST 的一个关键部分是发现,但是对于发现的真正含义的两种不同解释之间似乎存在很多争论:

  1. 开发人员发现:开发人员将大量 API 详细信息硬编码到客户端中,例如资源 URI、查询参数、支持的 HTTP 方法以及他们通过浏览文档和试验 API 响应发现的其他详细信息。恕我直言,这种类型的发现需要很酷的链接和 API 版本控制问题,并导致客户端代码与 API 的硬耦合。看起来并不比使用有据可查的 RPC 集合好多少。

  2. 运行时发现- 客户端应用程序本身能够找出它需要的一切,几乎没有或没有带外信息(大概,只有 API 处理的媒体类型的知识。)链接可能很热。但是为了使 API 非常高效,似乎需要对查询参数进行大量链接模板,这使得带外信息重新出现。可能还有其他我还没有想到的困难,因为我还没有想到发展到了那个地步。但我确实喜欢松散耦合的想法。

运行时发现似乎是 REST 的圣杯,但我看到很少有人讨论如何实现这样的客户端。我发现的几乎所有 REST 源似乎都假设开发人员发现。有人知道一些运行时发现资源吗?最佳实践?带有真实代码的示例或库?我正在为一个客户端使用 PHP(Zend 框架)。另一个是 Objective-C (iOS)。

考虑到开发人员社区目前的工具和知识,运行时发现是一个现实的目标吗?我可以编写我的客户端以不透明的方式处理所有 URI,但是如何最有效地做到这一点是一个问题,尤其是在低带宽连接上。无论如何,URI 只是等式的一部分。运行时上下文中的链接模板怎么样?除了发出很多 OPTIONS 请求之外,如何交流支持哪些方法?

4

6 回答 6

19

这绝对是一个难以破解的难题。在 Google,我们已经实现了我们的发现服务,我们所有的新 API 都是基于该服务构建的。TL;DR 版本是我们生成一个类似 JSON Schema 的规范,我们的客户可以解析 - 其中许多是动态的。

这意味着开发人员可以更轻松地升级 SDK,并为我们提供更轻松/更好的维护。

绝不是完美的解决方案,但我们的许多开发人员似乎都喜欢。

有关更多详细信息,请参阅链接(并确保观看视频。)

于 2012-02-09T02:19:36.530 回答
12

迷人。您所描述的基本上是 HATEOAS 原则。你问什么是 HATEOAS?阅读: http ://en.wikipedia.org/wiki/HATEOAS

用外行的话来说,HATEOAS 意味着链接跟踪。这种方法将您的客户端与特定 URL 分离,并让您可以灵活地更改 API 而不会破坏任何人。

于 2012-02-09T06:01:36.007 回答
6

你完成了你的家庭作业,并且深入到了它的核心:运行时发现是圣杯。不要追它。

UDDI 讲述了一个关于运行时发现的凄美故事:http ://en.wikipedia.org/wiki/Universal_Description_Discovery_and_Integration

于 2012-02-09T01:52:03.923 回答
5

在调用 API“RESTful”之前应该满足的要求之一是应该可以在该 API 之上编写通用客户端应用程序。使用通用客户端,用户应该能够访问所有 API 的功能。通用客户端是一种客户端应用程序,它不假定任何资源具有超出媒体类型定义的结构的特定结构。例如,Web 浏览器是一个通用客户端,它知道如何解释 HTML,包括 HTML 表单等。

现在,假设我们有一个用于网上商店的 HTTP/JSON API,并且我们想要构建一个 HTML/CSS/JavaScript 客户端,为我们的客户提供出色的用户体验。让该客户端成为通用客户端应用程序是一个现实的选择吗?不。我们希望为每个特定的数据元素和每个特定的应用程序状态提供特定的外观。我们不想在 API 中包含所有关于这些表现细节的知识,相反,客户端应该定义外观,API 应该只携带数据。这意味着客户端具有特定资源元素与特定布局和用户交互的硬编码耦合。

这是 HATEOAS 的终结以及 REST 的终结吗?是和不是

的,因为如果我们将有关 API 的知识硬编码到客户端中,我们就会失去 HATEOAS 的好处:服务器端的更改可能会破坏客户端。

,有两个原因:

  1. “RESTful”是 API 的属性,而不是客户端的属性。只要理论上可以构建一个提供 API 所有功能的通用客户端,API 就可以称为 RESTful。客户端不遵守规则的事实不是 API 的错。通用客户端会有糟糕的用户体验这一事实不是问题。如果我们实际上没有通用客户端,为什么知道可以拥有通用客户端很重要?这让我想到了第二个原因:
  2. RESTful API 为客户提供了选择他们想要的通用程度的选项,即他们想要的服务器端更改的弹性。需要提供出色用户体验的客户端可能仍能适应 URI 更改、默认值更改等。在没有用户交互的情况下执行批处理作业的客户端可能对其他类型的更改具有弹性。

如果您对实际示例感兴趣,请查看我的JAREST 论文。最后一节是关于 HATEOAS 的。您将看到,使用 JAREST,即使不是 100%,即使是高度交互且具有视觉吸引力的客户端也可以很好地适应服务器端的变化。

于 2015-11-02T11:15:50.903 回答
1

我认为关于 HATEOAS 的重要一点不是它是一些圣杯客户端,而是它将客户端与 URI 更改隔离开来——假设您正在使用已知(或开发人员发现的自定义)链接关系,这将允许系统知道对象的哪个链接是可编辑的表单。重要的一点是使用超媒体感知的 emdia 类型(例如 HTML、XHTML 等)。

于 2012-12-11T15:32:46.873 回答
0

你写:

为了使 API 非常高效,似乎需要对查询参数进行大量链接模板,这使得带外信息重新出现。

如果在上一个请求中提供了该链接模板,则没有带外信息。例如,一个 HTML 搜索表单使用链接模板 ( /search?q=%@) 来生成一个 URL ( /search?q=hateoas),但客户端(Web 浏览器)除了如何使用 HTML 表单和GET.

于 2013-08-06T15:03:26.350 回答