restful rest

在这篇文章中,我们将介绍有关HATEOAS的RESTful服务的综合文章。 超媒体是REST的秘密成分。

1.简介

在本教程的前一部分中,我们花了一些时间来刷新有关REST体系结构样式的基本原理的知识。 业界对REST状态的批判性眼光揭示了一个令人失望的事实,即作为应用程序状态引擎( HATEOAS )的超媒体 ,它的主要制约因素之一经常被完全省略。

目录

1.简介 2.所有这些“噪音”是什么? 3.野外的HATEOAS
3.1。 RFC 5988(网络链接) 3.2。 哈尔 3.3。 JSON:API 3.4。 JSON-LD 3.5。 警笛 3.6。 集合+ JSON 3.7。 优步 3.8。 亚哈皮 3.9。 石匠 3.10。 离子
4. HATEOAS的成本 5.案例研究 6。结论 7.接下来

超媒体由嵌入在信息表示中或作为信息表示之上的应用程序控制信息的存在来定义。 分布式超媒体允许将表示和控制信息存储在远程位置。

https://www.ics.uci.edu/~fielding/pubs/dissertation/web_arch_domain.htm#sec_4_1_3

这部分的主题是超媒体 ,尤其是HATEOAS 。 希望我们不仅可以确信它的重要性,而且可以支持许多策略,以利用超媒体功能丰富我们的REST Web服务和API。

2.所有这些“噪音”是什么?

众所周知,无状态是REST体系结构风格的强制性约束之一。 另一方面,绝大多数现实世界的Web服务和API必须处理状态管理。 看起来REST忽略了现代软件系统的现实和需求吗?

绝对不是, REST体系结构风格承认状态管理的重要性,并以超媒体 (应用程序状态引擎)的形式提出了解决方案。 在服务器端, 超媒体的使用不仅通告了资源之间的关系,而且还通告了可能应用于该资源的动作。 在客户端, 超媒体的存在带来了可发现性方面的下一步行动,步骤或要进行的状态转换。 理想情况下,客户端只需要知道一个URI入口点,其他所有内容都可以通过hypermedia来自服务器。

显然,客户端必须足够聪明,才能以可行的方式浏览超媒体控件。 正如许多经验丰富的Web服务和API开发人员已经注意到的那样,对服务器的超媒体支持并不那么困难,但是对客户端的支持却要困难得多。

但是,在Web服务和API的上下文中, 超媒体到底是什么? 我们可以将其视为服务器随响应发送给客户端的附加元信息。 它主要包括相关资源的链接,最重要的是,适用于所讨论资源以更改其状态的上下文操作。

当我说超文本时,我的意思是信息和控件的同时呈现,从而使信息成为用户通过其获得选择和选择动作的能力。 超媒体只是文本在媒体流中包含时间锚点的扩展。 大多数研究人员都放弃了这一区别。

https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven#comment-718

总之,这些元数据片段告诉客户端在哪里获取更多数据或在当前上下文中哪种操作有效。 如果您觉得这很刺激,那确实是。

因此,我们讨论了什么是超媒体以及它在REST体系结构风格中的重要地位,现在是时候讨论超媒体的“方式”了。

3.野外的HATEOAS

仅重申我们在上一部分中所说的内容, REST体系结构样式要求使用超媒体 ,但未指定如何使用它。 显然,这个漏洞必须关闭,并且多年来导致了各种样式和规格的泛滥。 许多公司走得更远,提出了自己的超媒体类型,蓝图和建议。

超媒体类型是MIME媒体类型,其中包含导致应用程序流的本机超链接语义。 例如,HTML是一种超媒体类型。 XML不是。

http://amundsen.com/hypermedia/

令人惊讶的是,到目前为止,还没有一个普遍接受的标准可以遵循,以使用超媒体元素来授权Web服务和API。 一些或多或少被广泛采用,而另一些则占据相当狭窄的位置。 而且,大多数规范仍在发展之中,并且在进行中时被广告宣传。

为什么会有这么多规格,主要区别是什么? 总的来说,弊端来自细节,更具体地说,在于描述相关的资源,链接和动作/操作。 如何找到最适合您的? 坦白地说,选择合适的规范会直接影响支持该规范所需的工作量。 如果是未开发的Web服务或API,您几乎可以自由选择。 相比之下,当您维护现有的Web服务或API并通过超媒体支持对其进行丰富的任务时,选择突然变得非常有限(除非您拥有完全重写的特权)。

从实现的角度来看,大多数规范都倾向于使用JSON格式来表示资源状态和超媒体控件。 但是,有些异常值会改用HTTP协议标头。 这当然不是由REST体系结构风格决定的,而是来自现代Web服务和API的现实,它们都是面向HTTP的。

因此,这些规格是什么?

RFC 5988(网络链接)

我们将从RFC-5988:Web链接开始 。 它指定Web链接的关系类型,为它们定义注册表,还定义HTTP头中带有特殊Link头的此类链接的使用。 这是一个简单的示例:

Link: <https://rentals.jcg.com/reservations>; rel="self"; title="reservations"

当然,在Link标头(或多个Link标头)中可能编码了多个Link ,例如:

Link: <https://rentals.jcg.com/reservations?page=1>; rel="previous"; title="previous page",
<https://rentals.jcg.com/reservations?page=3>; rel="next"; title="next page"

Web链接是引入超媒体支持的最基本,最简单的方法。 接受新的或现有的API相当简单,但是从功能的角度来看, Web链接提供的选项集非常有限,主要是简单的关系,并且不支持动作和集合 。

哈尔

JSON超媒体API语言或HAL建立使用JSON表示超媒体控件(链接和资源)的约定。 它由Mike Kelly于2011年创建。Web服务和API发出HAL文档,以便客户端可以提取适当的链接,并根据它们的关系类型在它们之间进行导航。

尽管HAL规范仍处于起草阶段 ,但其设计原理使其成为了由超媒体驱动的现代Web服务和API的首选之一。

HAL的主要设计目标是通用性和简单性。 HAL可以应用于许多不同的域,并施加了满足超媒体API关键要求所需的最少结构量。

https://tools.ietf.org/id/draft-kelly-json-hal-02.html

您可能会猜到,资源表示形式是JSON格式的HAL文档 ,这些文档使用专用的媒体类型application/hal+json

{"_embedded": {"reservations": [ {"id": "ce5886acbb87","vehicle": "Volkswagen Golf 1.2 TSI","from": "2020-02-01","to": "2020-02-12","_links": {"self": {"href": "https://rentals.jcg.com/reservations/ce5886acbb87"},"customer": {"href": "https://rentals.jcg.com/customers/fed195a03e9d"}}}, {"id": "fc14e8ef90f5","vehicle": "BMW 325i","from": "2020-01-10","to": "2020-01-12","_links": {"self": {"href": "https://rentals.jcg.com/reservations/fc14e8ef90f5"},"customer": {"href": "https://rentals.jcg.com/customers/fed195a03e9d"}}} ]},"_links": {"first": {"href": "https://rentals.jcg.com/reservations?page=0&size=10"},"self": {"href": "https://rentals.jcg.com/reservations?page=0&size=10"},"next": {"href": "https://rentals.jcg.com/reservations?page=1&size=10"},"last": {"href": "https://rentals.jcg.com/reservations?page=1&size=10"}},"page": {"size": 10,"totalElements": 13,"totalPages": 2,"number": 0}
}

除此之外, HAL还支持URI模板和链接关系文档。 不幸的是, HAL不提供任何行动支持(您可能听说过的另一个名字是Provided )。 试图填补HAL空白的衍生规范之一是HAL-FORMS 。 从本质上讲,它只是HAL的扩展,通过表达方法和属性的能力来增强它。

{                                                                       "id": "13e1892765c5",                                                "vehicle": "Honda Civic 2020",                                       "from": "2020-01-01",                                                "to": "2020-01-05",                                                  "_links": {                                                          "customer": {                                                      "href": "https://rentals.jcg.com/customers/fed195a03e9d"           },                                                                  "self": {                                                          "href": "https://rentals.jcg.com/reservations/13e1892765c5"        }                                                                   },                                                                    "_templates": {                                                      "default": {                                                       "method": "put",                                                 "properties": [ {                                                "name": "from","regex" : "yyyy-MM-dd","required": true}, {                                                              "name": "to","regex" : "yyyy-MM-dd","required": true}, {                                                              "name": "vehicle"                                              } ]                                                               },                                                                  "delete": {                                                        "method": "delete",                                              "properties": [ ]                                                }                                                                   }
}

请注意, HAL-FORMS旨在仅显示针对同一资源(或URI)可用的操作。 如果是JSON表示形式,则会为HAL-FORMS分配专用的媒体类型application/prs.hal-forms+json

JSON:API

JSON:API是受超媒体支持的Web服务和API的最广泛支持的标准之一。 它最初是由Yehuda Katz于2013年起草的,此后越来越受欢迎。 您可能会猜到,它仅适用于JSON表示形式。

JSON:API旨在最大程度地减少请求数量和客户端与服务器之间传输的数据量。 在不影响可读性,灵活性或可发现性的情况下实现了这种效率。

https://jsonapi.org/format/

JSON:API规范描述了链接,资源关系和资源修改(相当于动作)的语义。 另外,它涵盖了表示错误的方式。

{                                                                                                             "data": {                                                                                                  "id": "13e1892765c5",                                                                                    "type": "reservation",                                                                                   "links": {                                                                                               "self": "https://rentals.jcg.com/reservations/13e1892765c5"},                                                                                                        "attributes": {                                                                                          "from": "2020-01-01",                                                                                  "to": "2020-01-05",                                                                                    "vehicle": "Honda Civic 2020"                                                                          },                                                                                                        "relationships": {                                                                                       "customer": {                                                                                          "links": {                                                                                           "self": "https://rentals.jcg.com/reservations/13e1892765c5/relationships/customer",              "related": "https://rentals.jcg.com/reservations/13e1892765c5/customer"                          }                                                                                                     }                                                                                                       }                                                                                                         }
}

使JSON:API脱颖而出的原因在于,考虑了诸如排序,过滤,稀疏字段集和分页之类的获取(查询)模式,这些模式也是规范的一部分。

{"data": [{"id": "ce5886acbb87","type": "reservation","links": {"self": "https://rentals.jcg.com/reservations/ce5886acbb87"},"attributes": {"from": "2020-01-01","to": "0120-01-12","vehicle": "Volkswagen Golf 1.2 TSI"},"relationships": {"customer": {"links": {"self": "https://rentals.jcg.com/reservations/ce5886acbb87/relationships/customer","related": "https://rentals.jcg.com/reservations/ce5886acbb87/customer"}}}},{"id": "fc14e8ef90f5","type": "reservation","links": {"self": "https://rentals.jcg.com/reservations/fc14e8ef90f5"},"attributes": {"from": "2020-01-10","to": "2020-01-12","vehicle": "BMW 325i"},"relationships": {"customer": {"links": {"self": "https://rentals.jcg.com/reservations/fc14e8ef90f5/relationships/customer","related": "https://rentals.jcg.com/reservations/fc14e8ef90f5/customer"}}}}],"links": {"first": "https://rentals.jcg.com/reservations?page[limit]=2","last": "https://rentals.jcg.com/reservations?page[limit]=2&page[offset]=2","next": "https://rentals.jcg.com/reservations?page[limit]=2&page[offset]=2"},"meta": {"totalResourceCount": 3}
}

公平地说, JSON:API具有非常简单,可读和可理解的格式。 为了实现这种权衡,它做出了一些明智的决定。 例如,您不会直接在JSON:API文档中看到操作。 实际上,它们根据HTTP协议是隐式和隐式的: POST用于创建, PATCH用于修改, DELETE用于删除。 这可能会给客户带来一些解释上的困难,例如, PUT在哪里 ?

尽管JSON:API规范的1.0版在2015年崭露头角,但它正在积极地研究之中,并被认为是一个不断发展的文档。 JSON:API已正确注册了媒体类型名称application/vnd.api+json并且还拥有自己的JSON模式 定义 。

JSON-LD

JSON-LD是链接数据的基于JSON的序列化,在2014年就获得了W3C候选正式建议的地位。它可能是最活跃的社区,而该规范的最新版本JSON-LD 1.1的字面意思是已发布。一个月前。 JSON-LD设计背后的关键原则强调能够轻松集成到已经使用JSON的现有系统中,并使用JSON-LD语义对其进行扩充而不会破坏已建立的联系的能力。

可以肯定地说, JSON-LD比链接媒体更多的是链接数据,而不是超媒体,但是它具有丰富的表达信息,上下文和关系的能力非常符合某些超媒体的承诺。

{                                                               "@context": {                                                "@vocab": "http://schema.org/"                             },                                                            "@type": "Reservation",                                      "id": "13e1892765c5",                             "vehicle": "Honda Civic 2020",                               "from": "2020-01-01",                      "to": "2020-01-05",                        "customer": {                                                "@id": "https://rentals.jcg.com/customers/fed195a03e9d"      },                                                            "@id": "https://rentals.jcg.com/reservations/13e1892765c5"
}

JSON-LD的缺点之一是它缺乏对动作的支持。 Hydra解决了JSON-LD的主要缺点, Hydra是超媒体驱动的Web服务和API的词汇。

Hydra的基本思想是提供一个词汇表,使服务器可以将有效的状态转换通告给客户端。 然后,客户端可以使用此信息来构造HTTP请求,以修改服务器的状态,从而实现某个所需的目标。

http://www.hydra-cg.com/spec/latest/core/#hydra-at-a-glance

为了了解它是如何工作的,让我们看一下JSON-LD文档的快速示例,该示例已经丰富了Hydra语义。

{"@context": {"@vocab": "http://schema.org/","hydra": "http://www.w3.org/ns/hydra/core#"},"@type": "hydra:Collection","hydra:collection": [ {"@type": "hydra:Collection","@id": "https://rentals.jcg.com/reservations","hydra:manages": {"hydra:property": "self","hydra:subject": "https://rentals.jcg.com/reservations"},"hydra:operation": [ {"hydra:method": "GET"} ]} ],"hydra:member": [ {"@type": "Reservation","vehicle": "Volkswagen Golf 1.2 TSI","from": "2020-02-01","to": "2020-02-12","customer": {"@id": "https://rentals.jcg.com/customers/fed195a03e9d","hydra:operation": [ {"hydra:method": "GET"} ]},"@id": "https://rentals.jcg.com/reservations/ce5886acbb87","hydra:operation": [ {"hydra:method": "GET"}, {"hydra:method": "PUT","hydra:expects": {"@type": "UpdateReservation","hydra:supportedProperty": [ {"hydra:property": "from"}, {"hydra:property": "to"}, {"hydra:property": "vehicle"} ]}}, {"hydra:method": "DELETE"} ],"id": "ce5886acbb87"}, {"@type": "Reservation","vehicle": "BMW 325i","from": "2020-01-10","to": "2020-01-12","customer": {"@id": "https://rentals.jcg.com/customers/fed195a03e9d","hydra:operation": [ {"hydra:method": "GET"} ]},"@id": "https://rentals.jcg.com/reservations/fc14e8ef90f5","hydra:operation": [ {"hydra:method": "GET"}, {"hydra:method": "PUT","hydra:expects": {"@type": "UpdateReservation","hydra:supportedProperty": [ {"hydra:property": "from"}, {"hydra:property": "to"}, {"hydra:property": "vehicle"} ]}}, {"hydra:method": "DELETE"} ],"id": "fc14e8ef90f5"} ],"hydra:totalItems": 3,"hydra:view": {"@type": "hydra:PartialCollectionView","hydra:next": "https://rentals.jcg.com/reservations?page=1&size=2","hydra:first": "https://rentals.jcg.com/reservations?page=0&size=2","hydra:last": "https://rentals.jcg.com/reservations?page=1&size=2"}
}

再重申一次, JSON-LD的最强之处是数据链接。 与Hydra结合使用,您的Web服务和API将获得全面的超媒体功能,但是集成可能并不像人们期望的那么容易。 JSON-LD具有保留的媒体application/ld+json

警笛

Siren由Kevin Swiber于2012年撰写,是用于表示实体的超媒体规范。 Siren词汇表中的实体是URI可寻址资源,具有与之关联的属性,操作和可导航链接。 值得注意的是, Siren是专门为Web服务和API设计的,例如,动作可以直接映射到HTTP协议动词。

{                                                                                                    "class": [ "reservation" ],                                                                       "properties": {                                                                                   "id": "13e1892765c5",                                                                "from": "2020-01-01","to": "2020-01-05", "vehicle": "Honda Civic 2020"                                                                   },                                                                                                 "entities": [ {                                                                                   "rel": [ "customer" ],                                                                          "href": "https://rentals.jcg.com/customers/fed195a03e9d"                                          }, {                                                                                               "class": [ "customer" ],                                                                        "rel": [ "http://schema.org/customer" ],                                                        "properties": {                                                                                 "firstName": "John",                                                                          "lastName": "Smith",                                                                          "id" : "fed195a03e9d"                                                                  }                                                                                                } ],                                                                                               "actions": [ {                                                                                    "name": "update",                                                                               "method": "PUT",                                                                                "href": "https://rentals.jcg.com/reservations/13e1892765c5",                                      "fields": [ {                                                                                   "name": "from",                                                                               "type": "date"                                                                                }, {                                                                                             "name": "to",                                                                                 "type": "date"                                                                                }, {                                                                                             "name": "vehicle",                                                                            "type": "text"                                                                                } ]                                                                                              }, {                                                                                               "name": "delete",                                                                               "method": "DELETE",                                                                             "href": "https://rentals.jcg.com/reservations/13e1892765c5"                                       } ],                                                                                               "links": [ {                                                                                      "rel": [ "self" ],                                                                              "href": "https://rentals.jcg.com/reservations/13e1892765c5"                                       } ]
}

尽管Siren年龄较大 ,但仍被列为进行中的工作。 它本身不像HAL或JSON:API那样流行,但是它相对简单和Web API优先语义使其成为值得考虑的选择。 Siren JSON表示形式的媒体类型为application/vnd.siren+json

集合+ JSON

由Mike Amundsen在2011年创建的Collection + JSON规范旨在成为一种超媒体类型,旨在支持读取,编写和查询简单集合。 它受到Atom联合格式(RFC-4287)和Atom发布协议(RFC-5023)的启发。 关于Collection + JSON的一个有趣的事实是,它将所有内容都视为一个集合,因此,单个项目表示为一个元素的集合。

{"collection": {"version": "1.0","href": "https://rentals.jcg.com/reservations/13e1892765c5","links": [ {"rel": "customer","href": "https://rentals.jcg.com/customers/fed195a03e9d"} ],"items": [ {"href": "https://rentals.jcg.com/reservations/13e1892765c5","data": [ {"name": "from","value": "2020-01-01"}, {"name": "id","value": "13e1892765c5"}, {"name": "to","value": "2020-01-05"}, {"name": "vehicle","value": "Honda Civic 2020"} ],"links": [ {"rel": "customer","href": "https://rentals.jcg.com/customers/fed195a03e9d"} ]} ],"template": {"data": [ {"name": "from","value": ""}, {"name": "to","value": ""}, {"name": "vehicle","value": ""} ]}}
}

您可能会猜到, Collection + JSON标准非常适合列表和集合。 它还包括对查询模板 (链接和关系)和写模板 (操作)的支持,以及标准化的错误报告。

在某些时候, Collection + JSON非常流行,但是与其他替代方案相比,它实现起来可能更加困难。 同样,对“一切都是收藏”的偏见是不直观的。

Collection + JSON的媒体类型为application/vnd.collection+json

优步

UBER 超媒体类型描述了对简单状态转移和临时转移的支持。 它是由Mike Amundsen (是Collection + JSON的作者)和Irakli Nadareishvili于2014年左右共同创建的,同时针对XML和JSON变体。

那么,作者提出另一种超媒体类型的动机是什么? 迈克·阿蒙森 ( Mike Amundsen)的这则推文使推理过程更加清晰。

Collection + JSON是高度结构化的CRUD格式。 HAL适用于内联超媒体, Siren具有丰富的obj模型。 UBER开放且极简。

https://twitter.com/mamund/status/456508872832716800

UBER文档支持链接关系,操作和错误报告机制。 该规范旨在与多种协议配合使用,但包含有关基于HTTP的实现和解释的详细指南。

{"uber": {"version": "1.0","data": [ {"name": "customer","rel": [ "customer" ],"url": "https://rentals.jcg.com/customers/fed195a03e9d"}, {"name": "self","rel": [ "self" ],"url": "https://rentals.jcg.com/reservations/13e1892765c5"}, {"name": "update","rel": [ "update" ],"url": "https://rentals.jcg.com/reservations/13e1892765c5","action": "replace","model": "from={from}&to={to}&vehicle={vehicle}"}, {"name": "delete","rel": [ "delete" ],"url": "https://rentals.jcg.com/reservations/13e1892765c5","action": "remove","model": ""}, {"name": "reservation","data": [ {"name": "from","value": "2020-01-01"}, {"name": "id","value": "13e1892765c5"}, {"name": "to","value": "2020-01-05"}, {"name": "vehicle","value": "Honda Civic 2020"} ]} ]}
}

自2016年以来,它仍被标记为草稿(准确地说是稳定的草稿),并且没有太大变化。它没有正式注册的媒体类型,因此,如果使用JSON表示,则必须使用application/vnd.amundsen-uber+json

亚哈皮

有许多鲜为人知的超媒体规范仍然值得关注。 我们将从 2014年首次发布的Another Hypermedia(ish)API规范( Yahapi )开始,该规范本质上是启用 超媒体的约定的列表。

最后, Yahapi只是使您的API看起来漂亮,简单且一致的首选项列表。

https://github.com/Yahapi/yahapi

Yahapi提供了有关分页,排序,部分结果和错误格式的准则列表,支持链接和关系,但不幸的是不支持操作。 它很少在野外发现并且不是真正活跃。 Yahapi文档的媒体类型仅为application/json

石匠

Mason是一种基于JSON的格式,用于将超媒体元素引入经典的JSON数据表示中。 特别是,它包括用于链接和动作的超媒体元素以及标准化的错误处理。 Mason在媒体类型注册表中注册为application/vnd.mason+json

离子

Ion将自身定位为REST的一种基于JSON的直观超媒体类型。 它涵盖了关系类型的链接以及使用表单的操作 。 不幸的是,自2018年以来,该规范似乎处于Hibernate状态。分配给Ion内容的媒体类型为application/ion+json

4. HATEOAS的成本

此时,您应该对将超媒体和HATEOAS应用于RESTful Web服务和API时的作用有一个很好的了解。 而且,如果您是从事典型企业项目的经验丰富的软件开发人员,您可能很难记得上一次遇到HATEOAS时的情况。 让我们面对现实:没有人知道如何使用超媒体 。

在REST体系结构的上下文中, HATEOAS是必须的,但它不是免费的,并且会产生成本,有时非常重要。 不仅在实施方面,而且在前期设计方面。 在这方面,服务器相对容易,但是客户端确实很辛苦(充其量您可能会获得Link标头的支持)。 实际上,这意味着即使您开发完美的RESTful Web服务或API,其他开发人员也有很大可能选择完全不在其客户端中使用超媒体。

在本教程的这一部分中,我们讨论了许多不同的超媒体规范。 除少数例外,其中大多数带有“进行中”或“不稳定”的标签。 总的来说,这意味着仍有黑暗的水域在航行,而您最终到达那里的机会很高。 这就是为什么要持续不断地创建新规范的原因之一。 显然,每个规范需要非常不同的设计和实现工作量。 希望您的编程语言或平台生态系统已经有了一些库和框架来帮助您入门,但总的来说并非如此。

在服务器和客户端之间的数据交换方面, 超媒体可能会导致更多往返,以获取链接和关系背后的其他详细信息。 由于需要包括链接和操作,这也可能导致资源表示的大小大大增加。

您可能会问自己一个有趣的问题,即REST架构风格(尤其是HATEOAS)如何与微服务架构融合? 为了说明问题,请考虑一个只有两个微 Customer Service的系统,即Customer ServiceReservation Service 。 由于客户不需要任何额外的知识或前期知识,他们如何发现有多种服务? Reservation Service将如何纳入与客户相关的超媒体元素,反之亦然? 很有可能由另一层(例如API网关或/和聚合器)负责,并且听起来确实不是一个简单的问题。

如果此时您不惧怕超媒体和HATEOAS ,请不要担心。 收益大大超过了所需的成本和精力,尤其是从长期来看。 作为对此的确认,让我们看一下简短而简单的案例研究。

5.案例研究

我们将要分析的示例应用程序是一个汽车租赁平台,该平台目前仅实现两个RESTful Web API来管理reservationscustomers 。 与任何客户端共享的唯一知识是平台的入口点,出于演示目的,假设在伪造的URL https://rentals.jcg.com后面有服务器。

该端点仅接受HTTP GET请求并返回超媒体文档(使用HAL和HAL-FORMS ),示例如下所示。

$ curl https://rentals.jcg.com/
{                                                        "_links": {                                           "self": {                                           "href": "https://rentals.jcg.com/"                  },                                                   "reservations": {                                   "href": "https://rentals.jcg.com/reservations"      },                                                   "customers" : {                                      "href": "https://rentals.jcg.com/customers"         }                                                    }
}

超媒体感知客户端一旦收到此类文档,便可以清楚地了解到可以从那里导航到两个链接: reservationscustomers 。 在这种情况下,客户对reservations感兴趣,因此就去了那里。

$ curl -iv https://rentals.jcg.com/reservations
{"_embedded": {"reservations": [ {"id": "ce5886acbb87","vehicle": "Volkswagen Golf 1.2 TSI","from": "2020-02-01","to": "2020-02-12","_links": {"customer": {"href": "https://rentals.jcg.com/customers/fed195a03e9d"},"self": {"href": "https://rentals.jcg.com/reservations/ce5886acbb87"}},"_templates": {"default": {"method": "put","properties": [ {"name": "from","regex" : "yyyy-MM-dd","required": true}, {"name": "to","regex" : "yyyy-MM-dd","required": true}, {"name": "vehicle","required": true} ]},"delete": {"method": "delete","properties": [ ]}}}, ...]},"_links": {"self": {"href": "https://rentals.jcg.com/reservations"}},"_templates": {"default": {"method": "post","properties": [ {"name": "from","regex" : "yyyy-MM-dd","required": true}, {"name": "to","regex" : "yyyy-MM-dd","required": true}, {"name": "vehicle","required": true} ]}}
}

这次服务器返回强大的资源表示形式(为简单起见,集合中仅保留一个保留项),其中包含许多超媒体元素,因此客户端有多种选择。

例如,通过检查_templates 超媒体元素,它发现它可以通过在有效负载中提交包含fromtovehicle属性的HTTP POST请求来创建新的保留(因为它是HAL-FORMS ,所以使用application/x-www-form-urlencoded表单编码)。 您可能会注意到,尽管存在一些约束,但没有任何迹象表明fromtovehicle属性的类型(字符串?日期?数字?)是什么。

"_templates": {"default": {"method": "post","properties": [ {"name": "from","regex" : "yyyy-MM-dd","required": true}, {"name": "to","regex" : "yyyy-MM-dd","required": true}, {"name": "vehicle","required": true} ]}
}

备选地,客户端可以通过自省相关联的_templates 超媒体元素来表达对特定保留的兴趣。

"_templates": {"default": {"method": "put","properties": [ {"name": "from","regex" : "yyyy-MM-dd","required": true}, {"name": "to","regex" : "yyyy-MM-dd","required": true}, {"name": "vehicle","required": true} ]},"delete": {"method": "delete","properties": [ ]}
}

在这种情况下,服务器提供选择来使用HTTP PUT请求(完全替换语义)来更新保留,或者使用HTTP DELETE请求来完全删除特定的保留。

超媒体–结论

在本教程的这一部分中,我们讨论了超媒体和HATEOAS ,这是任何RESTful Web服务或API的组成部分。 超媒体规范的前景并非一成不变,并且在不断变化。 我们进行了很多选择,但没有遇到明显的赢家。 这样做的原因是,每一个都有不同的权衡,您需要确定哪种超媒体规范最适合您的应用程序需求。 上下文很重要,因此请认真对待。 您可能会发现有关为API选择超媒体类型的文章-HAL,JSON-LD,Collection + JSON,SIREN,噢,我的天哪! 由Kevin Sookocheff提供帮助。

7.接下来

在本教程的下一部分中,我们将讨论文档在由hypermedia支持的RESTful Web服务和API的生命周期中的作用。

翻译自: https://www.javacodegeeks.com/restful-services-with-hateoas-hypermedia-the-secret-ingredient-of-rest.html

restful rest

restful rest_HATEOAS的RESTful服务。 超媒体:REST的秘密要素相关推荐

  1. restful rest_HATEOAS的RESTful服务。 REST:刷新器

    restful rest 在这篇文章中,我们将介绍有关HATEOAS的RESTful服务的综合文章. REST:刷新器. 1.简介 "不好了! 请,不要再发表有关REST的文章!" ...

  2. 在 Docker 上运行一个 RESTful 风格的微服务

    tags: Microservice Restful Docker Author: Andy Ai Weibo: NinetyH GitHub: https://github.com/aiyanbo/ ...

  3. restful json_Dropwizard:轻松的RESTful JSON HTTP Web服务

    restful json 寻求快速, 轻松地创建可用于生产环境的RESTful JSON HTTP Web服务的Java开发人员应考虑使用Dropwizard框架. Dropwizard汇集了相互补充 ...

  4. Dropwizard:轻松的RESTful JSON HTTP Web服务

    寻求快速, 轻松地创建可用于生产环境的RESTful JSON HTTP Web服务的Java开发人员应该考虑Dropwizard框架. Dropwizard汇集了相互补充的广受好评的库,因此您可以了 ...

  5. 微服务开发的12项要素

    spring cloud官方文档提到的服务开发的12项要素. I. Codebase 从一个代码库部署到多个环境. II. Dependencies 使用显式的声明隔离依赖,即模块单独运行,并可以显式 ...

  6. restful和rest_HATEOAS的RESTful服务:JVM上的REST API和超媒体

    restful和rest 1.简介 到目前为止,我们已经花了很多时间谈论了相当数量的关于角色的的超媒体和HATEOAS在REST风格的 Web服务和API,扫视不同规格和可用性方面. 听起来好像支持超 ...

  7. HATEOAS的RESTful服务。 超媒体:REST的秘密要素

    在这篇文章中,我们将介绍有关HATEOAS的RESTful服务的综合文章. 超媒体是REST的秘密成分. 1.简介 在本教程的前一部分中,我们花了一些时间来刷新有关REST体系结构样式的基本原理的知识 ...

  8. 构建RESTful风格的WCF服务

    RESTful Wcf是一种基于Http协议的服务架构风格. 相较 WCF.WebService 使用 SOAP.WSDL.WS-* 而言,几乎所有的语言和网络平台都支持 HTTP 请求. RESTf ...

  9. java restful中文乱码_restful服务接口访问乱码 和 505错误

    标签: 用cxf 发部个rest服务,用浏览器访问和 HttpURLConnection 访问. 1. URL中有中文,浏览器访问正常,HttpURLConnection 失败. 解决: HttpUR ...

最新文章

  1. java怎么统计随机数出现次数,Excel统计出现次数、个数的VBA代码 java中怎么判断一个字符串中包含某个字符或字...
  2. opencv cv2.LUT()(使用查找表中的值填充输出数组)
  3. MongoDB学习笔记一ID自增长
  4. 在vue-cli中搭建mock服务器
  5. 3D 相机halcon算子,持续更新
  6. mysql如何优化性能优化_如何优化性能?MySQL实现批量插入以优化性能的实例详解...
  7. mysql中更新的命令是,mysql命令总结(陆续更新中)
  8. 【bzoj1911-[Apio2010]特别行动队】斜率优化
  9. luogu Cantor表
  10. 《穿越计算机的迷雾》读书笔记八
  11. 百度网盘获取下载链接
  12. 【pandas】reset_index函数详解
  13. 最优传输论文(六十四):Gradually Vanishing Bridge for Adversarial Domain Adaptation论文原理
  14. 快速安装到安卓手机软件
  15. JavaScript高级编程 III
  16. 子曾经曰过,我平生第一次讨厌下雨。
  17. GPUDockerfile实例:tensorflow-gpu
  18. python实战项目一:requests爬取淘宝图片
  19. 安装及配置Maven环境变量
  20. 会议主视觉_年会主视觉及延展设计内容doc

热门文章

  1. Game of Cards Gym - 102822G
  2. NOMURA Programming Contest 2021(AtCoder Regular Contest 121)
  3. YBTOJ:彩球抽取(期望)
  4. P3527-[POI2011]MET-Meteors【整体二分,树状数组】
  5. P1081-开车旅行【倍增,链表,dp】
  6. nssl1270-创世纪【树形dp,基环树】
  7. 纪中B组模拟赛总结(2020.2.22)
  8. Hadoop入门(十四)Mapreduce的数据去重程序
  9. JavaFX UI控件教程(二十三)之Menu
  10. MySQL date_format()函数