如何使用 Spring HATEOAS 放置和发布链接

Posted

技术标签:

【中文标题】如何使用 Spring HATEOAS 放置和发布链接【英文标题】:How to put and post links with Spring HATEOAS 【发布时间】:2014-12-05 00:10:36 【问题描述】:

我正在尝试了解如何在 Spring HATEOAS 中创建和修改链接。

例如,假设我有两个集合,一个在 api/users,另一个在 api/event。我想将用户 api/user/56 与事件 api/event/21 相关联。出于争论的原因,这是多对多的——一个用户可能参加很多活动,一个活动可能有很多用户。

据我了解,最好的方法是使用 URI 作为主键,因此我可能会将以下内容发布到 api/user/56/events;


    attends: "http://localhost:9090/api/event/21"

然后端点需要能够解析该 URL 并提取 ID(在本例中为 21)和控制器(EventController.class),以便我可以持久保存它。

问题 1:这是在 Spring Hateoas 中根据 REST API 处理关系的正确方法吗?

问题 2:如何在控制器中将此 url 解析为数据的可用句柄(例如对适当控制器/方法的引用、主键等)

研究

RestTemplate 可用于从请求映射方法内部的控制器请求数据,如下所示;

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<EventResource> response = restTemplate.getForEntity(attendsUrl, EventResource.class);
EventResource eventResource = response.getBody();

但是我不认为 eventResource 应该返回一个 Id 字段作为数据的一部分 - 它不是很安静,这会暴露在 API 上。一种方法是使用参数“includePK=true”,但这又感觉不对——它只是隐藏了问题。此外,服务器以这种方式向自己的 API 发出请求的想法似乎很迂回。

更新

这里有一个悬而未决的问题https://github.com/spring-projects/spring-hateoas/issues/292。基于该问题中的一些 cmets(用户 kevinconaway),我制作了一个快速实用程序类,在这里提供了一个简单的解决方案:SpringHateoasUtils。解决方案归结为;

String mapping = DISCOVERER.getMapping(targetClass, targetMethod);
UriTemplate template = new UriTemplate(mapping);
//values is key/value map of parameters that the referenced method accepts
Map<String, String> values = uriTemplate.match(uri);

SpringHateoasUtils 使它稍微好一点,但它仍然感觉应该是一个功能。我将寻求在 spring 代码中得到一些东西——当它清楚发生了什么时,我会回答这个问题。

【问题讨论】:

您只能发布http://localhost:9090/api/event/21。 Spring HATEOAS 不能帮助您取消引用 URL。它仅用于响应,而不是请求。你可以看看Spring Data REST 已经使用 Spring HATEOAS 几个月了,它似乎确实不能正确支持 REST,所以我不得不实施与您所描述的类似的解决方法。 【参考方案1】:

看这里的答案:

POSTing a @OneToMany sub-resource association in Spring Data REST

问题 1) 是的,这就是您发布链接/关系的方式。使用 URI。

问题 2) 从客户端的角度来看,资源的 URI 实际上它的 ID。服务器在内部自动将此 URI 解析为实际的模型实例,使用

org.springframework.data.rest.core.UriToEntityConverter.convert(...)

【讨论】:

这是一个关于 Spring Hateoas 的问题 - 尽管 Spring Data Rest 允许有限地使用链接,但 Spring Data Rest 没有提供一种实现自己的链接处理功能的方法。 你好安德鲁!你看过我贴的链接吗?我也花了一段时间来理解细微的差异。但与此同时,我发现了如何归档您正在尝试做的事情:Spring Data HATEOAS 允许通过发布文本/uri-list 例如“创建”实体之间的链接。像这样:curl -X PUT -H "ContentType: text/uri-list" http://localhost:8080/api/myEntitty/1 链接 uri 作为有效负载 http://localhost:8080/api/myLinkedChildEntity/4711 如果您需要更多低级访问,您可以随时在 spring rest 中实现自己的 @RestController

以上是关于如何使用 Spring HATEOAS 放置和发布链接的主要内容,如果未能解决你的问题,请参考以下文章

将 Zuul、Hystrix(和 Feign)与 Spring Cloud HATEOAS 一起使用时如何转发标头?

Spring Data Rest 和 Hateoas

强制spring hateoas生成https链接而不是http

在 Spring Boot 应用程序中使用 API 网关时,HATEOAS 路径无效

Spring Boot:HATEOAS 和自定义 JacksonObjectMapper

Spring HATEOAS 与 Spring Data Rest