RESTful Web服务可发现性,第4部分

这是有关使用Spring 3.1和Spring Security 3.1和基于Java的配置来建立安全的RESTful Web Service的系列文章的第四篇 。 本文将重点介绍REST API,HATEOAS的可发现性以及由测试驱动的实际方案。

引入REST可发现性

API的可发现性是一个值得引起足够关注的主题,因此很少有API能够正确地实现它。 如果做得正确,这也可以使API不仅具有RESTful和可用性,而且具有优雅的风格。

要了解可发现性 ,需要了解这种约束,即“超媒体作为应用程序状态引擎(HATEOAS)”; RESTful API的这种约束是关于作为应用程序状态唯一驱动程序的超媒体(实际上是超文本)对资源上的动作/转换的完全可发现性。 如果交互作用是由API通过对话本身(特别是通过超文本)来驱动的,那么就没有文档 ,因为这会迫使客户端做出实际上不在API上下文之外的假设。

此外,继续这种逻辑思路,确实可以认为RESTful API的唯一方法是,如果它可以从根完全发现并且没有先验知识 ,这意味着客户端应该能够通过在GET上进行GET来导航API。根。 展望未来,所有状态更改均由客户端使用REST API在表示形式中提供的可用且可发现的转换来驱动(因此称为Representational State Transfer )。

总之,服务器应具有足够的描述性,以指示客户端如何仅通过超文本来使用API​​,在HTTP对话的情况下,该超文本可能是Link标头。

具体的可发现性场景(由测试驱动)


那么,REST服务可被发现意味着什么? 在本节中,我们将使用Junit, rest-assured和Hamcrest来测试可发现性的各个特征。 由于REST Service已在该系列的第3部分中得到保护,因此在使用API​​之前,每个测试都需要首先进行身份验证 。 还需要一些实用程序来解析响应的Link标头。

发现有效的HTTP方法
当使用无效的HTTP方法使用RESTful Web服务时,响应应为405 METHOD NOT ALLOWED ; 此外,它还应该使用响应中的“ 允许 HTTP标头”来帮助客户端发现该特定资源所允许的有效HTTP方法:

@Test
public void whenInvalidPOSTIsSentToValidURIOfResource_thenAllowHeaderListsTheAllowedActions(){// Givenfinal String uriOfExistingResource = this.restTemplate.createResource();// WhenResponse res = this.givenAuthenticated().post( uriOfExistingResource );// ThenString allowHeader = res.getHeader( HttpHeaders.ALLOW );assertThat( allowHeader, AnyOf.<String> anyOf( containsString("GET"), containsString("PUT"), containsString("DELETE") ) );
}

发现新创建的资源的URI
使用位置 HTTP标头,创建新资源的操作应始终在响应中包括新创建资源的URI。 如果客户端在该URI上执行GET,则该资源应可用:

@Test
public void whenResourceIsCreated_thenURIOfTheNewlyCreatedResourceIsDiscoverable(){// WhenFoo unpersistedResource = new Foo( randomAlphabetic( 6 ) );Response createResponse = this.givenAuthenticated().contentType( MIME_JSON ).body( unpersistedResource ).post( this.paths.getFooURL() );final String uriOfNewlyCreatedResource = createResp.getHeader( HttpHeaders.LOCATION );// ThenResponse response = this.givenAuthenticated().header( HttpHeaders.ACCEPT, MIME_JSON ).get( uriOfNewlyCreatedResource );Foo resourceFromServer = response.body().as( Foo.class );assertThat( unpersistedResource, equalTo( resourceFromServer ) );
}

该测试遵循一个简单的场景:创建一个新的Foo资源,并使用HTTP响应来发现该资源现在可访问的URI 。 然后,测试会更进一步,并对该URI进行GET检索以获取资源并将其与原始资源进行比较,以确保资源已正确保留。

发现URI以获取该类型的所有资源
当我们获取特定的Foo实例时,我们应该能够发现下一步可以做什么:我们可以列出所有可用的Foo资源。 因此,获取资源的操作应始终在其响应中包含URI,以在何处获取该类型的所有资源,再次使用Link标头:

@Test
public void whenResourceIsRetrieved_thenURIToGetAllResourcesIsDiscoverable(){// GivenString uriOfExistingResource = this.restTemplate.createResource();// WhenResponse getResponse = this.givenAuthenticated().get( uriOfExistingResource );// ThenString uriToAllResources = HTTPLinkHeaderUtils.extractURIByRel( getResponse.getHeader( "Link" ), "collection" );Response getAllResponse = this.givenAuthenticated().get( uriToAllResources );assertThat( getAllResponse.getStatusCode(), is( 200 ) );
}

该测试解决了REST中链接关系的一个棘手问题:要检索所有资源的URI使用rel =“ collection”语义。 这种类型的链接关系尚未标准化,但已被多种微格式使用 ,并已提出标准化要求。 非标准链接关系的使用打开了有关RESTful Web服务中的微格式和更丰富语义的讨论。

其他可能发现的URI和微格式

其他URI可能会通过Link标头发现,但是在没有转移到更丰富的语义标记(例如定义 自定义链接关系 , Atom发布协议或微格式)的情况下 ,现有的链接关系类型只有这么多。另一篇文章。

例如,如果在特定资源上执行GET时客户端可以发现URI来创建新资源,那将是一个很好的选择。 不幸的是,与模型创建语义没有链接关系。 幸运的是,标准做法是创建的URI与获取该类型的所有资源的URI相同,唯一的区别是POST HTTP方法。

结论

本文介绍了RESTful Web服务上下文中可发现性的一些特征,讨论了HTTP方法发现,创建和获取之间的关系,发现URI以获取所有资源的关系等。在接下来的文章中,我将重点介绍从root ,分页,自定义链接关系,Atom发布协议以及Spring REST服务中的Discoverability的实际实现开始发现API。 同时,检查github项目 。

参考: RESTful Web服务可发现性,我们的JCG合作伙伴 Eugen Paraschiv在baeldung博客上的第4部分 。

相关文章 :

  • 使用Spring 3.1和基于Java的配置引导Web应用程序,第1部分
  • 使用Spring 3.1和基于Java的配置构建RESTful Web服务,第2部分
  • 使用Spring Security 3.1保护RESTful Web服务,第3部分
  • Spring的REST服务发现性,第5部分
  • 使用Spring Security 3.1的RESTful服务进行基本身份验证和摘要身份验证,第6部分
  • Spring&Quartz集成自定义注释
  • Spring MVC拦截器示例
  • 在运行时交换出Spring Bean配置

翻译自: https://www.javacodegeeks.com/2011/12/restful-web-service-discoverability.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374158.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10位IT领袖给应届毕业生的10条忠告

10位IT领袖给应届毕业生的10条忠告&#xff0c;在走向独立和自主的伟大征程中&#xff0c;吸取他们的经验。 在毕业生们迈出象牙塔之时&#xff0c;他们应该听从哪些人的建议&#xff1f;在走向独立和自主的伟大征程中&#xff0c;他们该吸取哪些教训&#xff1f;听一听各领域…

ubuntu安装好后常用软件安装和配置

1、安装vim sudo apt install vim 安装好后进入路径打开vimrc文件&#xff0c;这里需要注意一定要用sudo不然编辑后无法保存&#xff01; cd /etc/vim sudo vim vimrc 在最下面加入 set nu set ts4 set softtabstop4 set shiftwidth4 set expandtab set autoindent 依次是…

Objective-c 数据类型

这里列出Objective-c中独有数据类型&#xff1a; 一、字符串 在Objective-c中&#xff0c;字符串常量是由和一对从引号括起的字符串序列。比如&#xff1a;"China"、"objective-c"等都是合法的字符串常量。 二、id类型 id类型是Objective-c中一个比较独…

JBoss AS 7 EJB3池配置

现在&#xff0c;AS 7.0.1已经发布&#xff0c;让我们看一下可用的EJB3新功能。 就像我在上一篇文章中提到的那样 &#xff0c;AS 7.0.1现在允许您为无状态会话bean和MDB配置池。 当前&#xff0c;我们允许在子系统级别配置池&#xff0c;这意味着该池将适用于服务器上部署的所…

iOS开发网络篇—文件的上传

说明&#xff1a;文件上传使用的时POST请求&#xff0c;通常把要上传的数据保存在请求体中。本文介绍如何不借助第三方框架实现iOS开发中得文件上传。 由于过程较为复杂&#xff0c;因此本文只贴出部分关键代码。 主控制器的关键代码&#xff1a; YYViewController.m 1 #import…

var模型的matlab实现_Eviews中VAR模型的操作、脉冲响应分析和方差分解的实现

打开文件所在位置&#xff0c;获取数据。选中变量右键open打开var操作EViews,在VAR对象的工具栏中选择“View”|“Lag Structure”|“AR Roots Table/ AR Roots Graph”选项&#xff0c;得到AR根的表和图。结果显示&#xff1a;VAR模型所有根模的倒数都小于1&#xff0c;即都在…

一个程序员的爱情表白书

我能抽象出整个世界 但是我不能抽象出你 因为你在我心中是那么的具体 所以我的世界并不完整 我可以重载甚至覆盖这个世界里的任何一种方法 但是我却不能重载对你的思念 也许命中注定了 你在我的世界里永远的烙上了静态的属性 而我不慎调用了爱你这个方法 当我义无返顾的…

结构体、枚举类型

一、结构体 结构体&#xff1a;就是一个自定义的集合&#xff0c;里面可以放各种类型的元素&#xff0c;用法大体跟集合一样。 1、定义的方法&#xff1a; struct student { public int nianling; public int fenshu; public string name; public string sex; public int sum; …

NXP KW38开发杂记(一)MCUXpress 运行进入NMI_Handler

这里是大佬的具体分析过程&#xff0c;感兴趣可以看看 https://www.cnblogs.com/wenhao-Web/p/13618703.html 解决办法&#xff1a; 在startup_mkw38a4.c文件里&#xff0c;定位到Flash_Config {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE}; 把最后一个参数0xFFFFFFFE改…

25个让Java程序员更高效的Eclipse插件

Eclipse提供了一个可扩展插件的开发系统。这就使得Eclipse在运行系统之上可以实现各种功能。这些插件也不同于其他的应用&#xff08;插件的功能是最难用代码实现的&#xff09;。拥有合适的Eclipse插件是非常重要的&#xff0c;因为它们能让Java开发者们无缝的开发基于J2EE和服…

NXP KW38蓝牙开发(一)入门第一课:官网蓝牙广播和连接例程,NMI禁止

首先要下载开发使用的IDE&#xff1a;MCUXpresso IDE 下载链接&#xff1a; 进入nxp的官网&#xff0c;搜索KW38 向下翻看&#xff0c;找到Xpresso&#xff0c;点击进入 习惯使用IAR开发的同学也可以下IAR版本&#xff0c;这里以Xpresso为例 下载好后安装&#xff0c;一路默…

rough and crude

rough:物理上的粗糙或者说不平&#xff0c;高尔夫球场的生草区 crude:原始、未经加工的那种粗&#xff0c;即没有精加工转载于:https://www.cnblogs.com/dgyw/p/5767078.html

views 多个文件夹 netcore_.NET Core中的使用Kestrel服务器理解及应用

Kestrel是一个基于libuv的跨平台.NET Core web服务器&#xff0c;libuv是一个跨平台的异步I/O库。ASP.NET Core模板项目使用Kestrel作为默认的web服务器。Kestrel支持以下功能&#xff1a;HTTPS用于启用不透明升级的WebSockets位于Nginx之后的高性能Unix socketsKestrel 被.NET…

使用PowerMock测试对象的内部状态

大多数单元测试都集中于测试对象的行为以证明其有效。 这可以通过编写一个JUnit测试来实现&#xff0c;该测试调用对象的公共方法&#xff0c;然后测试这些调用的返回值是否与先前定义的一组期望值匹配。 这是一种非常常见且成功的技术。 但是&#xff0c;不应忘记对象也显示状…

布局

1&#xff09;ul li 把ul宽度设置大一点&#xff0c;然后overflowhidden;&#xff08;最好不要嵌套使用&#xff0c;原因看清除浮动方法&#xff09;&#xff0c;然后外面必须有包裹的div壳&#xff0c;div壳的宽度就按设计稿来&#xff0c;这样就避免了需要给最后一个li设置m…

10个职场故事,让人不得不看

1、强盗师徒 有一次&#xff0c;一个老强盗带着徒弟去抢劫银行&#xff0c;被警方追捕。两人狂逃&#xff0c;差点儿连裤子都跑掉了。好不容易甩掉了警察&#xff0c;两人上气不接下气&#xff0c;瘫倒在地上。 良久&#xff0c;惊魂稍定&#xff0c;徒弟说:“师父啊师父&#…

NXP UWB NCJ29D5开发(一)环境搭建

1、从NXP的共享账号下载资料 共享账号需要找对接的NXP人员拿到&#xff0c;他会把资料分享到这个账号&#xff0c;在这个账号里面可以下载 进入nxp官网&#xff0c;登录后点击my nxp&#xff0c;选择Software Licensing and Support 进入后接着选择View accounts 进入后选择…

西瓜创客python编程进阶收费_西瓜创客和编程猫有什么不同?哪个更值得报名?...

看情况来决定即可&#xff0c;在课程内容上其实出入我觉得不是很大&#xff0c;重点是教学服务、师资、授课模式等&#xff0c;单纯我自己的角度来说&#xff0c;我个人偏向于西瓜创客多一点&#xff0c;他们家的课程更具有趣味性&#xff0c;游戏化教学&#xff0c;融入卡通人…

Stack的三种含义

作者&#xff1a;阮一峰 学习编程的时候&#xff0c;经常会看到stack这个词&#xff0c;它的中文名字叫做”栈”。 理解这个概念&#xff0c;对于理解程序的运行至关重要。容易混淆的是&#xff0c;这个词其实有三种含义&#xff0c;适用于不同的场合&#xff0c;必须加以区分。…

NXP UWB NCJ29D5开发(二)BlinkyLed例程

路径为UWB\NCJ29D5\NCJ29D5_CAS_Examples_v1.4\onic\BlinkyLed\toolsupport\keil 例程怎么来的可以看看上一篇NXP UWB NCJ29D5开发&#xff08;一&#xff09;环境搭建 1、 //系统选择外部晶振&#xff0c;时钟频率为55.2Mhz phscaAppHal_Init(PHSCA_APPHAL_XO_CLOCK_SOURCE_…