RESTful API运行时可发现性/ HATEOAS客户端设计


79

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

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

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

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

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


2
在您的OPTIONS参考资料上仅需稍作改动。您可以使用“允许”标头在OPTIONS请求之外传达允许的资源操作。Roy Fielding甚至将标头视为一种超文本形式-参见此处
paulkmoore,2012年

听到一个gr8问题,关键问题给出了适用的方法列表,客户端是否应该能够为常规的CRUD操作形成网址,或者将其称为“带外”?说,如果我们也提供CRUD操作的链接,那么您如何在json中“形成”表单?可能是,如果您使用特定于应用程序的媒体类型,而您不需要做“形式”,但是wat是发现媒体类型(即json模式)的标准方法,那么发现模式的过程将被视为不是“超出范围”。乐队”?
redzedi

xhtml看起来非常好,而且流畅,但是如果您必须执行json,那么我想现在是
不定的

Answers:


19

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

这样的结果意味着开发人员可以更轻松地进行SDK升级,而我们则可以轻松/更好地进行维护。

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

请参阅链接以获取更多详细信息(并确保观看视频。)


是否有任何标准为我们自己的API实现这种发现服务?
ÇağatayGürtürk

12

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

用外行的术语来说,HATEOAS表示链接跟随。这种方法使您的客户端与特定的URL脱钩,并且使您可以灵活地更改API,而不会破坏任何人。



4

可以将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%。


1

我认为HATEOAS的重要意义不是客户端,而是它将客户端与URI更改隔离开-假设您使用的是已知(或开发人员发现的自定义)链接关系,它将使系统能够知道对象的哪个链接是可编辑形式。重要的一点是使用超媒体感知的emdia类型(例如HTML,XHTML等)。


0

你写:

为了使API非常有效,似乎需要对查询参数进行大量的链接模板处理,从而使带外信息重新出现。

如果在先前的请求中提供了该链接模板,则没有带外信息。例如,HTML搜索表单使用链接模板(/search?q=%@)生成URL(/search?q=hateoas),但是客户端(网络浏览器)除了如何使用HTML表单和之外什么都不知道GET


确实没有带外信息-客户端负责使用提供的资源/实例数据扩展uri模板(并且应该知道如何执行此操作)-json-schema.org/latest/json-schema- hypermedia.html#anchor18
福西2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.