7.2 使用Traverson导航REST API
7.2 使用Traverson导航REST API
Traverson来源于Spring Data HATEOAS项目,是Spring应用中开箱即用的消费超媒体API的解决方案。这个基于Java的库灵感来源于同名的JavaScript库。
你可能已经发现Traverson的名字有点类似于“traverse on”,这种叫法其实可以很好地描述它的用法。在本节中,我们将会以遍历API关系名的方式来消费API。
要使用Traverson,首先我们要用API的基础URI来实例化一个Traverson对象:
1 | Traverson traverson = new Traverson( |
在这里,我将Traverson指向了Taco Cloud的基础URL(本地运行)。这是需要给Traverson指定的唯一URL。从这里开始,我们就可以根据链接的关系名来遍历API。我们同时还指定了API将会生成JSON格式的响应,并且具有HAL风格的超链接,这样Traverson就能知道怎样解析传入的资源数据了。与RestTemplate类似,你可以选择在使用Traverson对象之前实例化它,也可以将其声明为一个bean并在需要的地方注入进来。
有了Traverson对象之后,我们就可以通过以下链接使用API。例如,假设我们想检索所有配料的列表。从6.3.1小节可以知道,配料链接有一个href属性,它会链接到配料资源。我们需要跟踪这个链接:
1 | ParameterizedTypeReference<Resources<Ingredient>> ingredientType = |
通过调用Traverson对象的follow()方法,我们就可以导航至链接关系名为ingredients的资源。现在,客户端已经导航至ingredients,我们需要通过调用toObject()来提取资源的内容。
我们需要告诉toObject()方法要将数据读入到哪种对象之中。考虑到我们需要以Resources<Ingredient>
对象的形式来读入,而且Java类型擦除使得为泛型提供类型信息变得非常困难,所以这可能会有些棘手。但是,创建ParameterizedTypeReference能够帮助我们解决这个问题。
打个比方,假设这不是REST API,而是Web站点上的主页;这也不是REST客户端代码,而是我们正在浏览器中查看主页。在页面中,我们看到了一个关于Ingredients的链接,点击进入该链接。在进入下一个页面的时候,我们需要读取该页面,类似于Traverson将内容提取为Resources<Ingredient>
对象。
现在,我们考虑一个更有趣的场景——假设我们想要获取最新创建的taco。从主资源开始,我们可以按照如下方式导航至最近的taco资源:
1 | ParameterizedTypeReference<Resources<Taco>> tacoType = |
在这里,我们跟踪tacos链接,然后从这里开始,跟踪recents链接。通过这种方式,我们得到了感兴趣的资源,所以基于对应的ParameterizedTypeReference调用toObject()方法,我们就得到了想要的内容。我们可以通过列出关系名称列表的形式来简化“.follow()”方法:
1 | Resources<Taco> tacoRes = |
正如我们所看到的,Traverson能够很容易地导航HATEOAS的API并消费其资源。但是,它并没有提供通过这些API写入或删除资源的方法。相反,RestTemplate能够写入和删除资源,但是在导航API方面支持得并不太好。
当你既要导航API又要更新或删除资源时,你需要组合使用RestTemplate和Traverson。Traverson仍然可以导航至创建新资源的链接。然后,可以将这个链接传递给RestTemplate来执行POST、PUT、DELETE或任何其他需要的HTTP请求。
例如,我们想要为Taco Cloud菜单添加一个新的Ingredient,如下的addIngredient ()方法将Traverson和RestTemplate组合起来,向API提交了一个新的Ingredient:
1 | private Ingredient addIngredient(Ingredient ingredient) { |
在跟踪完Ingredients之后,我们通过调用asLink()方法得到链接本身。基于该链接,我们调用getHref()得到链接的URL。有了URL之后,我们就具备了使用RestTemplate调用postForObject()并创建新配料所需的一切。