HATEOAS:简洁的描述

我试图得到对HATEOAS的清晰和简明的理解,而我绝不是一个专家WRT REST(我想我明白了,这要感谢http://tomayko.com/writings/rest-to-my-妻子 )

任何人都可以build议一个同样令人生气的博客/文章WRT HATEOAS?

超媒体约束(以前称为HATEOAS)是一个约束,用于为用户代理提供指导。

通过在返回的表示中包括链接,服务器可以消除来自用户代理的确定基于当前应用状态可以采取什么动作的负担,并知道为了实现该目标而与谁进行交互。

由于服务器不知道用户代理的当前状态,而不是它在请求中接收到的状态,所以用户代理试图避免使用除了从服务器返回的表示之外的状态是非常重要的。 这确保服务器提供的可用操作基于对用户代理状态的最完整理解。

符合超媒体约束的用户代理就像一个状态机,其中状态转换是由当前表示中可用的后续链接引起的 。 返回的表示成为新的状态。

这种方法的好处可以是一个非常轻量级的用户代理 。 它需要很less的代码来pipe理状态,因为它的行为应该完全基于接收到的响应和检索该响应的链接。 用户代理代码变成声明性的,被动的,而不是GET的命令序列,然后做这个,然后做这个,你只需要有下面的链接机制和许多当你收到这个时候这样做。

有关如何工作的例子 ,您只需要浏览器和一个不使用Javascript的网站。 浏览器向您展示基于HTML链接的选项。 当你关注这个链接的时候,浏览器用跟随链接时检索到的新状态replace它的当前状态。 后退button工作(或至less应该),因为你是从历史上的链接检索状态。 浏览器不应该关心你如何进入页面,因为状态应该完全基于检索到的表示。

这种“状态pipe理”模式可能非常有限 ,因为您当前的应用程序状态基于单个服务器响应。 但是, 复杂的应用程序可以通过使用一组用户代理协同工作来构build 。 这是AJAX实现的一部分,它允许使用不同的用户代理进行单独的请求,因此实际上是pipe理另一个状态机。 不幸的是,大多数时候,人们在开始制作javascript请求时会回到RPC风格,这不幸的是考虑到Javascript的自然asynchronous。

HATEOAS用几句话来说: 在输出的数据中,使用URI来引用其他资源,而不是ID。

就像所有简短的定义一样,我刚刚给出的定义在很多层面都是错误的,但是它应该让你明白HATEOAS的核心是什么。

现在,再解释一下。

HATEOAS原则规定,应用程序的状态应通过超文本链接提前。 想想你在网上浏览。 首先你必须在地址栏中input一个地址。 从这一点来说,你的导航几乎只能感谢点击链接:你点击一个链接,最后到另一个页面。 再点击一下,出现另一个页面。 浏览器如何将你从第一页移动到第二页到第三页? 它使用<a>元素编码的URL。

同样,如果您的REST应用程序产生这个结果

 <accomodation> <hotel info="http://example/hotel/0928374" price="200"/> <guest-house info="http://example/guest-h/7082" price="87"/> </accomodation> 

那么接收应用程序将不必访问任何外部知识来源以知晓第一个酒店在http://example/hotel/0928374 ,并且第二个在http://example/guest-h/7082处可用。

另一方面,如果您的应用程序生成类似ID的响应

 <accomodation> <hotel id="0928374" price="200"/> <guest-house id="7082" price="87"/> </accomodation> 

接收的应用程序必须事先知道如何将ID与前缀组合在一起以获得每个住宿的信息可用的URI(例如“添加http://example/给每个请求,然后添加hotel给酒店和guest-h )。 您可以看到,这种机制与许多DB应用程序中发生的情况类似,但与浏览器的工作方式不同。

遵循HATEOAS原则是很重要的,因为它允许应用程序在接收应用程序不发生剧烈变化的情况下发展。 假设您想将您的URI从http://example.com/hotel/0928374更改为https://reviews.example.com/accommodation/0928374 。 如果你跟着HATEOAS就是一个简单的改变:修改返回的值,它是:接收应用程序将继续工作,无需任何修改。 相反,如果您有单独的关于如何构buildURI的文档,则必须联系所有应用程序开发人员,并要求他们注意文档已更新,并且应该更改其代码以反映更改。

免责声明:这是一个简单的答案,只是抓住了问题的表面。 但是,如果你得到这个,你有80%的HATEOAS原则。

REST和HATEOAS的一个问题是界面定义的难度和缺乏可见性和控制。 使用更传统的RPC风格的交互,通常会有一个artifact,如IDL或WSDL,它们定义了API,并且可以由项目进行控制和pipe理。

使用HATEOAS,API是dynamic可parsing的,可以将其描述为一组行为(状态更改)。 行为在代码中描述。 API描述(WADL)是从代码生成的,而不是从接口描述生成的代码。

这篇文章帮助我彻底理解它。 http://restcookbook.com/Basics/hateoas/

它简单而优雅。

HATEOAS代表超文本作为应用程序状态的引擎 。 这意味着应该使用超文本来find你通过API的方式。 一个例子:

 GET /account/12345 HTTP/1.1 HTTP/1.1 200 OK <?xml version="1.0"?> <account> <account_number>12345</account_number> <balance currency="usd">100.00</balance> <link rel="deposit" href="/account/12345/deposit" /> <link rel="withdraw" href="/account/12345/withdraw" /> <link rel="transfer" href="/account/12345/transfer" /> <link rel="close" href="/account/12345/close" /> </account> 

除了我们账户中有100美元的事实,我们可以看到4个选项:存入更多的钱,取钱,转账到另一个账户,或closures我们的账户。 “链接”标签允许我们找出指定操作所需的URL。 现在,假设我们银行没有100美元,但我们实际上是在红色的:

 GET /account/12345 HTTP/1.1 HTTP/1.1 200 OK <?xml version="1.0"?> <account> <account_number>12345</account_number> <balance currency="usd">-25.00</balance> <link rel="deposit" href="/account/12345/deposit" /> </account> 

现在我们是红色的25美元。 你现在看到我们失去了很多select,只有存款有效吗? 只要我们红了,我们就不能closures我们的账户,也不能转账或从账户中提取任何款项。 超文本实际上告诉我们什么是允许的,什么不是:HATEOAS

从我个人使用HATEOAS引擎的经验来看,最大的区别就是devise本身的哲学。

如果我们要构build一个Web应用程序,有两种方法。 一个是RPC风格,另一个是REST风格。

如果状态必须以RPC风格进行testing,则需要调用返回结果的RPC过程。 通过这种devise方法,第一次调用之后返回的参数必须存储在客户机上,以便进一步的调用可以使用返回的参数。 这只是使客户端和服务器紧密耦合,使整个系统有状态。

而在REST风格中,没有RPC。 重要的是客户端和服务器之间的交互。 对于任何状态转换,客户端必须与服务器交互以获取信息。 唯一固定的交互是家庭互动。 其余的都是由客户通过不同的互动发现。

从计算机科学的angular度来看,程序风格是algorithm。 REST风格是一个交互范式。 任何采用互动范式作为语言的系统都将提供一个HATEOAS系统。