7.2 使用 Traverson 引导 REST API
7.2 使用 Traverson 引导 REST API
Traverson 附带了 Spring Data HATEOAS,作为在 Spring 应用程序中使用超媒体 API 的开箱即用解决方案。这个基于 Java 的库的灵感来自于同名的类似的 JavaScript 库(https://github.com/traverson)。
你可能已经注意到 Traverson 的名字听起来有点像 “traverse on”,这是描述它用法的好方式。在本节中,将通过遍历关系名称上的 API 来调用 API。
要使用 Traverson,首先需要实例化一个 Traverson 对象和一个 API 的基础 URI:
Traverson traverson = new Traverson(
URI.create("http://localhost:8080/api"), MediaType.HAL_JSON);
这里将 Traverson 指向 Taco Cloud 的基本 URL(在本地运行),这是需要给 Traverson 的唯一 URL。从这里开始,将通过链接关系名称来引导 API。还将指定 API 将生成带有 HAL 风格的超链接的 JSON 响应,以便 Traverson 知道如何解析传入的资源数据。与 RestTemplate 一样,可以选择在使用 Traverson 对象之前实例化它,或者将它声明为一个 bean,以便在需要的地方注入它。
有了 Traverson 对象,可以通过以下链接开始使用 API。例如,假设想检索所有 Ingredient 的列表。从第 6.3.1 节了解到,Ingredient 链接有一个链接到配料资源的 href 属性,需要点击这个链接:
ParameterizedTypeReference<Resources<Ingredient>> ingredientType =
new ParameterizedTypeReference<Resources<Ingredient>>() {};
Resources<Ingredient> ingredientRes =
traverson.follow("ingredients").toObject(ingredientType);
Collection<Ingredient> ingredients = ingredientRes.getContent();
通过调用 Traverson 对象上的 follow() 方法,可以引导到链接关系名称为 ingredients 的资源。现在客户端已经引导到 ingredients,需要通过调用 toObject() 来提取该资源的内容。
toObject() 方法要求你告诉它要将数据读入哪种对象。考虑到需要将其作为 Resources
打个比方,假设这不是一个 REST API,而是一个网站的主页。设想这是在浏览器中查看的主页,而不是 REST 客户端代码。在页面上看到一个链接,上面写着 Ingredient,然后点击这个链接。当到达下一页时,将读取该页,这类似于 Traverson 以 Resources
现在让我们考虑一个更有趣的用例,假设想获取最近创建的 tacos,从 home 资源开始,可以引导到最近的 tacos 资源,像这样:
ParameterizeTypeReference<Resources<Taco>> tacoType =
new ParameterizedTypeReference<Resources<Taco>>() {};
Resources<Taco> tacoRes =
traverson.follow("tacos").follow("recents").toObject(tacoType);
Collection<Taco> tacos = tacoRes.getContent();
在这里可以点击 Tacos 链接,然后点击 Recents 链接。这会将你带到你所感兴趣的资源,因此使用适当的 ParameterizedTypeReference 调用 toObject() 可以得到想要的结果。调用 follow() 方法可以通过列出跟随的关系名称来简化:
Resources<Taco> tacoRes =
traverson.follow("tacos", "recents").toObject(tacoType);
Traverson 可以轻松地引导启用了 HATEOAS 的 API 并调用其资源。但有一件事它没有提供任何方法来编写或删除这些 API。相比之下,RestTemplate 可以编写和删除资源,但不便于引导 API。
当需要同时引导 API 和更新或删除资源时,需要同时使用 RestTemplate 和 Traverson。Traverson 仍然可以用于引导到将创建新资源的链接。然后可以给 RestTemplate 一个链接来执行 POST、PUT、DELETE 或任何其他 HTTP 请求。
例如,假设想要向 Taco Cloud 菜单添加新的 Ingredient。下面的 addIngredient() 方法将 Traverson 和 RestTemplate 组合起来,向 API POST 一个新 Ingredient:
private Ingredient addIngredient(Ingredient ingredient) {
String ingredientsUrl = traverson.follow("ingredients")
.asLink().getHref();
return rest.postForObject(ingredientsUrl,
ingredient,
Ingredient.class);
}
在 follow Ingredient 链接之后,通过调用 asLink() 请求链接本身。在该链接中,通过调用 getHref() 请求链接的 URL。有了 URL,就有了在 RestTemplate 实例上调用 postForObject() 并保存新 Ingredient 所需的一切。