11

我试图了解如何在 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:就 REST API 而言,这是在 Spring Hateoas 中处理关系的正确方法吗?

问题 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。基于该问题的一些评论(由用户kevinconaway 提供),我制作了一个快速 util 类,在这里提供了一个简单的解决方案: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 代码中为此获取一些东西 - 当它清楚发生了什么时,我将回答这个问题。

4

1 回答 1

3

看看这里的答案:

在 Spring Data REST 中发布 @OneToMany 子资源关联

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

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

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

于 2017-01-05T08:17:49.537 回答