HATEOAS REST Service

用户通过点击页面的href的链接地址,而跳转到其他网页,实现浏览网页的过程了。

-> 让调用REST的api就可以实现,类似于用户浏览网页的从一个页面跳转到另外一个页面的过程了

-> 而这种超链接方式的api用于告诉用户:该资源的只允许哪些操作(比如GET,POST),以及不允许哪些操作(比如DELETE

-> 从而达到方便用户更加清楚使用你的接口的目的

关于HATEOAS的最佳实践:不用HATEOAS

但是HATEOAS的缺点也很明显:

就把简单的返回的信息,搞的更加复杂了。

也因此实际在开发REST的api过程中,至少我是很少采用这个规范的。

当然,也有和我持同样观点的,比如这位

-》这样会让前端解析API时,倒是变得更加复杂了。显得多此一举和增加复杂度了。

而之前自己在折腾选择好的Flask的REST API的框架期间,本来觉得eve不错,后来就是由于发现eve默认使用HATEOAS,把返回的json搞的太复杂,而放弃eve的。

顺带提及一点的是:

针对于HATEOAS标准,也还有是别人会用的。

所以一些流行的REST的框架中,有些也是内置支持了HATEOAS

比如:FlaskREST框架:

https://crifan.github.io/http_restful_api/website/

那么HATOEAS带来了什么优势?

一个显而易见的好处是,只要客户端总是使用Link Rel来获取URI,那么服务端可以在不破坏客户端实现的情况下实现URI的修改,从而进一步解耦客户端和服务端。

另一个容易被忽视的优势是它可以帮助客户端开发者探索API,Links实际上提示了开发者接下来可以进行何种业务操作,开发者虽然精通技术,但往往对于业务不甚了解,这些提示可以帮助他们理解业务,至少是一个查询API文档的好起点。想象一下,如果某个API的响应中多了一个新的Link,敏感的开发者可能就会询问这个Link是用来做什么的,是一个新的特性吗?虽然看起不起眼,但这往往使两个团队的成员沟通起来更容易。

https://insights.thoughtworks.cn/hateoas-of-single-page-application/

JSON Hypermedia Types
JSON媒体类型没有提供原生的超链接语法,所以为了解决这个问题,有几种JSON超媒体类型被创建出来:

• HAL—http://stateless.co/hal_specification.html
• JSON-LD—http://json-ld.org
• Collection+JSON—http://amundsen.com/media-types/collection/
• JSON API—http://jsonapi.org/
• Siren—https://github.com/kevinswiber/siren
HAL是其中最流行的一种,而且被Spring Framework支持。

HAL
HAL(The Hypertext Application Language)是简单的超媒体类型,由Mike Kelly于2011创建。它同时支持XML和JSON格式。HAL媒体类型定义了一种资源,它是状态的容器、links的集合、嵌套资源的集合。如下图所示:

 

HATEOAS((Hypermedia as the Engine of Application State)
可以看做对于一般以JSON为例的返回数据在文件依赖关系(rel)

及url路径(href)上的再描述。

Spring HATETOS 的目标是解决两个问题:link creation 及representation assembly

默认的Spring使用HAL render responses 
HAL 定义Links 在return的文本中作为性质被包含
使用这种方法可以完成resource discoverability
通过一层一层的json返回数据中的links可以找到所有的资源。

HAL(Hypertext Application Language)
expressing hypermedia controls such as Links wlth JSON

HAL 是WEB API可以以Link进行发展的组织形式 
其对于serving及 consuming hypermedia提供了一致的接口

要理解RESTful架构,最好的方法就是去理解Representational State Transfer这个词组,直译过来就是「表现层状态转化」,其实它省略了主语。「表现层」其实指的是「资源」的「表现层」,所以通俗来讲就是:资源在网络中以某种表现形式进行状态转移。分解开来:

  • Resource:资源,即数据。比如newsfeed,friends,order等;
  • Representational:某种表现形式,比如用JSON,XML,JPEG等;
  • State Transfer:状态变化。通过HTTP动词实现。

然后再来理解一个具体的RESTful架构——面向资源的架构(Resource-Oriented Architecture,ROA):

  • 资源是由URI来指定。所谓「上网」,就是与互联网上一系列的「资源」互动,调用它的URI。
  • 对资源的操作包括获取、创建、修改和删除资源,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
  • 通过操作资源的表现形式来操作资源。具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定。
  • 资源的表现形式则是XML或者HTML,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。

https://blog.csdn.net/fengxinziyangyang/article/details/51458952

https://blog.csdn.net/why_2012_gogo/article/details/77195387

  • 该约束是 REST 服务的基础,是客户端和服务器之间的桥梁。该约束又包含下面 4 个子约束。
    • 资源标识符。每个资源都有各自的标识符。客户端在请求时需要指定该标识符。在 REST 服务中,该标识符通常是 URI。客户端所获取的是资源的表达(representation),通常使用 XML 或 JSON 格式。
    • 通过资源的表达来操纵资源。客户端根据所得到的资源的表达中包含的信息来了解如何操纵资源,比如对资源进行修改或删除。
    • 自描述的消息。每条消息都包含足够的信息来描述如何处理该消息。
    • 超媒体作为应用状态的引擎(HATEOAS)。客户端通过服务器提供的超媒体内容中动态提供的动作来进行状态转换。这也是本文所要介绍的内容。

在了解 REST 的这些约束之后,就可以对“表达性状态转换”的含义有更加清晰的了解。“表达性”的含义是指对于资源的操纵都是通过服务器提供的资源的表达来进行的。客户端在根据资源的标识符获取到资源的表达之后,从资源的表达中可以发现其可以使用的动作。使用这些动作会发出新的请求,从而触发状态转换。

HATEOAS is a concept of application architecture. It defines the way in which application clients interact with the server, by navigating hypermedia links they find inside resource models returned by the server.

To implement HATEOAS you need some standard way of representing resources, that will contain hypermedia information (links to related resources), for example, something like this:

{
    "links": {
        "self": { "href": "http://api.com/items" },
        "item": [
            { "href": "http://api.com/items/1" },
            { "href": "http://api.com/items/2" }
        ]
    },
    "data": [
            { "itemName": "a" }, 
            { "itemName": "b" } 
    ] 
}

HAL is one of such standards. It is a specific format of resource presentation, that can be used to implement HATEOAS.

You can fully implement HATEOAS without following HAL at all if you prefer to follow another standard or use your own.

https://stackoverflow.com/questions/25819477/relationship-and-difference-between-hal-and-hateoas

Sun公司的Craig McClanahan为什么现有“REST”API没有真正使用RESTful服务中的“超媒体即应用状态引擎(HATEOAS)”提供了答案。他从最近参与的Sun云计算API  设计中举例说明了这样做的好处。

我们一开始假设服务只能发布一个众所周知的URI(返回一个包含调用者可访问的云资源表示[representation]的云表示,它也可以是一个URI链接)。通过检查这些表示就可以发现整个系统中的其他每个URI(包括所有完成状态改变的URI)。

Craig建议通过资源图来让超媒体给客户端提供指导;通过把资源及其关系描述成指向它们的超媒体,可以让交互式的Web应用完成用户可以完成的工作;让客户端有效地浏览资源表示,驱动应用状态的改变。他认为,这样设计的好处是:

  • 降低客户端编码错误。大约90%的错误出现在为服务器构造正确URI的过程中。典型错误是遗漏路径片断(Path Segment),以错误的顺序获取它们,或者忘记URL编码的东西。
  • 减少无效的状态转换调用。[……]举个例子[出自云计算API……],你只有“部署”了虚拟机(VM),才能去“启动”它。服务器知道URI发起了每次状态改变(通过POST),但是VM的表示只罗列出了由当前状态可以有效转换的那些状态转变的URI。
  • 无需破坏客户端就可进行细粒度演变。每次在编写REST API客户端时,都会对系统能做什么进行一些假设。但是,如果你仅记录那些“需要知道的表示内容”,再加上那些不会破坏先前行为的服务器端规定,你就能在不破坏所有客户端的情况下快速演变API,或者在服务器上同时支持API的多个版本。

Marc Hadley在他的帖子中对讨论进行了补充,提到可以使用WADL进行描述……

……一组URI和URI模板,依赖客户端去构建URI来访问它们需要的资源,云计算API只发布一个“根”URI,并记录下客户端可以在表示中哪个位置找到用来遍历服务的其他URI。

他描述了一种对Web应用进行文档化的可能方式,如Sun云计算API使用WADL,并通过例子解释了其想法。

  1. 使用资源类型描述每种资源,
  2. 对表示进行参数化,以标识内嵌于它们中的链接
  3. 定义每个内嵌于链接标识中的资源类型。

请阅读原贴,并可在rest讨论组中进行讨论。

查看英文原文:Advantages Of (Also) Using HATEOAS In RESTFul APIs

http://www.infoq.com/cn/news/2009/04/hateoas-restful-api-advantages

原文地址:https://www.cnblogs.com/softidea/p/9595277.html