HATEOAS的RESTful服务。 记录超媒体API

1.简介

希望本教程前一部分不仅揭示了超媒体HATEOAS的深远影响,而且使我们确信这些都是RESTful Web服务和API的基本构建块。 在这一部分中,我们将继续侧重于文档方面,以解决如何预先传递Web服务或API功能的问题。

在进一步介绍之前,让我们根据REST体系结构样式从服务提供者和服务使用者的角度详细说明手头的问题。 本质上, 超媒体驱动的Web服务和API的可发现性方面允许服务提供者发布单个URL,入口点并以此完成。 另一方面,任何意识到超媒体的消费者都应该能够使用上下文链接浏览资源,并在必要时沿途完成任何所需的状态修改。 唯一的前提条件是提供者和消费者应该说相同的超媒体方言 。 这是关于提供者/消费者交互的机器角度,这是探索性客户端的示例。

现在,让我们从开发人员的角度来看这个问题。 您将如何知道特定资源的属性? 您如何知道期望使用哪种类型的链接和链接关系? 它支持的行动或能力如何? 它们可能导致什么副作用? 最后,作为开发人员,您只需要满足一个简单的要求,例如“客户C希望将其预订R再延长一周”。 这是人类对提供者/消费者交互的观点。

很多具有挑战性的问题,但是我们有答案吗? 让我们找出……

2. OpenAPI和朋友

如今,如果我们研究推荐记录RESTful Web服务和API的推荐方法是什么,那么您无疑会遇到OpenAPI规范 。 规范有多个版本,但在撰写本文时,最新版本是3.0.2

OpenAPI规范OAS )定义了与RESTful API的语言无关的标准接口,使人类和计算机都可以发现和理解服务的功能,而无需访问源代码,文档或通过网络流量检查。 正确定义后,使用者可以使用最少的实现逻辑来理解远程服务并与之交互。

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md

公平地说, OpenAPI是一个很好的规范,它是许多组织和个人出色的协作成果的结果。 它已被广泛认为是记录RESTful Web服务和API的首选方法,但它并不是唯一的方法。 其他良好的规范,例如RAMLAPI蓝图RSDLWADLAPI Builderiodocstinyspec也正在使用中,值得了解。

OpenAPI和朋友可以完成这项工作,但是从根本上讲,这些规范集中在资源位置, 几乎没有或没有超媒体支持。

超媒体而言,它完全破坏了资源位置。 超媒体驱动的RESTful Web服务和API并非是静态的,远非如此,大多数机器或人类需要了解的内容都是在运行时共享的。

3. OpenAPI不是答案,现在呢?

您可能经常碰到超媒体RESTful Web服务和API转换为资源周围的状态机的说法。 从概念上讲,这是有道理的,因为超媒体带来了状态和过渡的明确定义的语义。

而不是资源位置,我们应该专注于描述资源本身。 资源描述至少应包括其数据语义,受支持的可能动作(状态转换)(如果可能,取决于上下文)以及相关的可导航资源(与关系类型的链接)。

应用程序级配置文件语义(ALPS)

应用程序级配置文件语义ALPS )可能是最先进的,包含最广泛的规范,用于在RESTful Web服务和API的上下文中记录和共享超媒体的语义。

ALPS文档可以用作配置文件,以解释具有与应用程序无关的媒体类型(例如HTML, HALCollection + JSONSiren等)的文档的应用程序语义。 这样可以提高配置文件在各种媒体类型之间的可重用性。

http://www.alps.io/spec/index.html

概要文件的作用是为人类和机器建立共享的结构化词汇表。 简而言之,概要文件允许定义数据的语义和过渡以及包括文档的能力。

使用通用媒体类型(HTML,Atom, Collection + JSON等)实现超媒体客户端/服务器应用程序时,客户端和服务器实例需要共享对特定于域的信息的理解,例如数据元素名称,链接关系值,和状态传输参数。 该信息与正在实施的应用程序(例如会计,联系人管理等)直接相关,而不是与表示中使用的媒体类型相关。

http://www.alps.io/spec/index.html

在本教程上一部分中,我们已经看到了许多实现RESTful Web服务和API的规范,让我们尝试通过ALPS支持来扩展其中之一(例如HAL )。

$ 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"
    },
    "profiles": {
      "href": "https://rentals.jcg.com/alps"
    }
  }
}

案例研究中的示例相比,您可能会注意到服务器还返回了一个附加的链接profiles 。 让我们看看它的背后。

$ curl https://rentals.jcg.com/alps
{                                                                
  "version": "1.0",                                             
  "doc": {                                                                                    
    "href": "https://rentals.jcg.com/documentation.html"        
  },                                                             
  "descriptor": [ {                                             
    "id": "customers",                                           
    "href": "https://rentals.jcg.com/alps/customers"               
  }, {                                                           
    "id": "reservations",                                        
    "href": "https://rentals.jcg.com/alps/reservations"            
  } ]                                                            
}

到目前为止,我们已经发布了两个配置文件描述符, customersreservations 。 让我们更深入地了解reservations配置文件描述符。

$ curl https://rentals.jcg.com/alps/reservations
{                                            
  "version": "1.0",                         
  "descriptor": [ {                         
    "id": "reservation",                    
    "type": "SEMANTIC",                     
    "descriptor": [ {                       
      "id": "from",                         
      "type": "SEMANTIC"                    
      "href": "https://schema.org/Date"
    }, {                                     
      "id": "id",                           
      "type": "SEMANTIC"                    
      "href": "https://schema.org/Thing#identifier"
    }, {                                     
      "id": "to",                           
      "type": "SEMANTIC",
      "href": "https://schema.org/Date"
    }, {                                     
      "id": "vehicle",                      
      "type": "SEMANTIC",
      "href": "https://schema.org/Vehicle#name"
    } ]                                      
  }, {                                       
    "id": "create",                           
    "name": "reservations",                 
    "type": "UNSAFE",                         
    "rt": "#reservation"                    
  }, {                                       
    "id": "list",                           
    "name": "reservations",                 
    "type": "SAFE",                         
    "rt": "#reservation"                    
  }, {                                       
    "id": "customer",                       
    "name": "customer",                     
    "type": "SAFE",                         
    "href": "https://rentals.jcg.com/alps/customers"
    "rt": "#customer"                       
  }, {                                       
    "id": "update",                         
    "name": "reservation",                  
    "type": "IDEMPOTENT",                   
    "rt": "#reservation"                    
  }, {                                       
    "id": "delete",                         
    "name": "reservation",                  
    "type": "IDEMPOTENT",                   
    "rt": "#reservation"                    
  } ]                                        
}

值得花一些时间并简要介绍一下此个人资料。 它概述的第一件事是reservation描述符,用于描述数据语义(属性及其类型)。 之后,将提供动作和过渡的描述符数量( createlistdeleteupdatecustomer )。

附带说明一下,尽管在我们的示例中,概要文件是由应用程序制作的,但是ALPS还具有注册表概念( ALPS概要文件注册表),以允许概要文件定义被重用和引用。 已经从schema.org定义中预先构建了大量ALPS配置文件,并且可以从http://alps.io/schema.org获得

回到主题,让我们看一下使用HAL样式作为参考的ALPS配置文件如何渗透到资源表示中。

{                                                                                            
  "id": "13e1892765c5",                                                                     
  "vehicle": "Honda Civic 2020",                                                            
  "from": "2020-01-01",                                                                     
  "to": "2020-01-05",                                                                       
  "_links": {                                                                               
    "profile": {                                                                               
      "href": "https://rentals.jcg.com/alps/reservations#reservation"                                      
    },                                                                                       
    "customer": {                                                                           
      "href": "https://rentals.jcg.com/customers/fed195a03e9d",
      "profile": "https://rentals.jcg.com/alps/customers#customer"
    },                                                                                       
    "self": {                                                                               
      "href": "https://rentals.jcg.com/reservations/13e1892765c5"                             
    }                                                                                        
  },                                                                                         
  "_templates": {                                                                           
  …
  }                                                                                          
}

HAL文档已得到充实,以包括指向各自资源配置文件的profile 链接关系 。 或者,有时可以看到Links头对于发送回资源​​配置文件信息很有用。

Links: profile="https://rentals.jcg.com/alps/reservations#reservation"

总体而言, ALPS规范是描述RESTful Web服务和API的资源语义和转换的一种非常简单且人性化的方式。

ALPS与JSON-LD,...

一些超媒体规范对数据语义(词汇)具有一流的支持。 一个很好的例子是带有@vocab上下文定义的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"     
}

当依赖超媒体规范时,资源语义详细信息将作为资源表示的一部分。 无论如何,这是有价值的信息。 相反, ALPS配置文件与资源表示形式和媒体类型分开存在,可以独立查询和解释。

JSON超模式

JSON模式是一种基于JSON的格式,用于描述JSON数据的结构。 JSON Hyper-Schema规范具有指定超链接和与超媒体相关的关键字的功能,从而丰富了JSON Schema词汇表。

JSON Hyper-Schema是一个JSON Schema词汇表,用于通过超链接注释JSON文档以及用于通过HTTP等超媒体环境处理和操纵远程JSON资源的指令。

https://tools.ietf.org/html/draft-handrews-json-schema-hyperschema-02

ALPS相比, JSON Hyper-Schema提供了更为丰富的语义,用于描述数据,链接(关系)和操作(负担)。 以下示例只是为reservation资源构建JSON Hyper-Schema的一种可能性。

{
    "title": "Reservation",
    "type": "object",
    "properties": {
        "id": {
            "title": "Unique Reservation identifier",
            "type": "string"
        },
        "vehicle": {
            "title": "Name of the vehicle",
            "type": "string"
        },
        "from": {
            "title": "Start date",
            "type": "date"
        },
        "to": {
            "title": "End date",
            "type": "date"
        }
    },
    "required" : ["from", "to", "vehicle"],
    "links": [
        {
            "rel": "self",
            "href": "{id}"
        },
        {
            "title": "Customer",
            "rel": "customer",
            "href": "/reservation/{id}/customer"
        },
        {
            "title": "Cancel Reservation",
            "rel": "delete",
            "href": "{id}",
            "method": "DELETE"
        },
        {
            "title": "Update Reservation",
            "rel": "update",
            "href": "{id}",
            "method": "PUT",
            "schema": {
                "type": "object",
                "properties": {
                    "vehicle": {
                        "title": "Name of the vehicle",
                        "type": "string"
                    },  
                    "from": {
                        "title": "Start date",
                        "type": "date"
                    },
                    "to": {
                        "title": "End date",
                        "type": "date"
                    }  
                },
                "required": ["vehicle", "to", "from"]
            }
        }
    ]
}

突出的第一件事可能是每个链接和操作所具有的详细程度。 您可能会注意到的直接缺点之一是语义(例如, delete动作)与具体的指针(例如href模板)交织在一起。

微格式

除了ALPSJSON Hyper-Schema外 ,还有一些鲜为人知的规范,值得一提。 微格式就是其中之一。

微格式是为人为先设计的,其次是为机器设计的, 微格式是一组基于现有标准和广泛采用的标准的简单,开放的数据格式。 微格式不是要扔掉今天有用的东西,而是要通过适应当前的行为和使用模式来首先解决更简单的问题。

http://microformats.org/wiki/about

微格式的最新版本称为microformats2

Microformats2取代并取代了两种经典的微格式 (有时称为microformats1),并且结合了从微数据RDFa中获得的经验教训。

http://microformats.org/wiki/microformats2

微格式的主要目标是HTML媒体类型( 语义HTML ),因此它不一定最适合大多数RESTful Web服务和API。

都柏林核心元数据计划(DCMI)

最初的都柏林核心规范发布于1995年,是一组15个(最初为13个)核心元素,用于描述资源语义。 因此, 都柏林核心元数据计划DCMI )是一个旨在支持跨各种目的和业务模型的元数据设计和最佳实践创新的组织。 它定义了更丰富的规范DCMI元数据术语

总的来说, Dublin Core是致力于应用程序配置文件链接数据 (尤其是基于RDF词汇表)的开拓性工作之一。 多年来,它所管理的规范数量已经大大增加,而不仅仅是元数据。

微格式一样 ,对于RESTful Web服务和API来说, 都柏林核心和相关规范的广泛范围可能不是您的首选。

4。结论

在本教程的这一部分中,我们讨论了用丰富的超媒体支持来记录RESTful Web服务和API的挑战。 公平地说,这是一个已解决的问题的说法远非事实。 如今OpenAPI规范已成为事实上的选择,但尚未将超媒体视为一流的公民。 最突出的替代方案,尤其是应用程序级配置文件语义(ALPS)JSON Hyper-Schema ,无疑正在朝着正确的方向前进,但是,两者仍在进行中。

5.下一步是什么

在本教程的下一部分中,我们将通过在JVM平台(使用Java)上设计和实现成熟的RESTful Web服务API,从理论转向实践。

翻译自: https://www.javacodegeeks.com/restful-services-with-hateoas-documenting-hypermedia-apis.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值