【问题标题】:Navigating through HATEOAS with Spring client使用 Spring 客户端浏览 HATEOAS
【发布时间】:2016-05-06 22:27:02
【问题描述】:

我们有一个 API,它使用 Spring JPA 并通过 REST 提供对我们数据库中某些数据的访问。此 API 以 Hateoas 方式公开(我们使用的是 Spring 实现)。

我们现在正在考虑是坚持使用这种方法还是手动编写 s=我们自己的 REST 接口。现在,我已经阅读了很多关于 HATEOAS 的文章,但我不确定使用它的最大优势是什么。当然,我知道我可以使用链接浏览它,但我仍然需要知道每个级别的链接是否存在,对吗?

为了说明我的问题,假设我有以下结构:

server.com/
- /store
- /users/

server.com/users
- /managers/
- /other/

server.com/managers
- list of entities with ids

我想使用此 API 并获取所有“经理”实体(位于 server.com/users/managers 下)

使用 Spring 引导链接时正确的做法是什么?

选项一:

  RequestEntity<Void> request = RequestEntity.get("server.com/users/managers").accept(HAL_JSON).build();
  final Resource<Manager> managers = restTemplate.exchange(request, new ResourcesType<Manager>() {
        }).getBody();

选项二:

   // global endpoint
   RequestEntity<Void> request = RequestEntity.get("server.com").accept(HAL_JSON).build();
   final Resource<Object> rootLinks = restTemplate.exchange(request, new ResourceType<Object>() {
        }).getBody();

    Links links = new Links(rootLinks.getLinks());
    final Link userLink = links.getLink("users").expand();

    // users endpoint
    request = RequestEntity.get(URI.create(userLink.getHref())).accept(HAL_JSON).build();
    final Resource<Object> managerLinks = restTemplate.exchange(request, new ResourceType<Object>() {
        }).getBody();

    links = new Links(managerLinks.getLinks());
    final Link managerLink = links.getLink("managers").expand();

    // managers endpoint
    request = RequestEntity.get(URI.create(managerLink.getHref())).accept(HAL_JSON).build();
    final Resources<Manager> resourceAccounts = restTemplate.exchange(request, new ResourcesType<Manager>() {
        }).getBody();

第一个选项看起来很简单,我可以通过单个请求获取所有实体。但是,如果我只使用这种方法,我看不到热 Hateoas 是有益的。 Spring 文档指出,不建议使用硬编码链接。

第二种方法似乎更符合 Hateoas 的风格,但它创建了三个请求,只是为了获取我已经知道的位置的资源。这似乎也不对。

我知道这可能是一个愚蠢的问题,但有人可以解释一下我显然缺少的 Hateoas 背后的好主意吗?

【问题讨论】:

  • 我不明白这一点,如果您需要知道“经理”是“用户”(“用户/经理”)的子路径。我认为相反,您应该从根(“全局”)端点直接公开指向“用户/经理”(以及所有其他常用资源)的链接。这样您就可以重新排列 URL(即“员工/经理”),而无需更改客户端。正如一位同事常说的:“少考虑 URL 结构,多关注资源类型”。
  • 那么,当您对 API 一无所知时,Hateoas 的重点是帮助导航?此 API 主要通过我们系统中的其他服务以编程方式访问(不涉及人工交互)。我想 Hateoas 在这里没有用处……但你总是至少要知道一些关于结构的知识,对吧?我只是觉得我完全错过了 Hateoas 的意义
  • 这里还是有用的。 REST API 通常不供(直接)人类使用。您绝对需要了解有关 API 的一些信息。关键是,您需要知道的是资源类型及其关系,而不是它们的 URL 结构。不过我不是专家,这就是为什么我还没有尝试回答你的问题。 ;-)
  • 你为什么不使用 *spring traverson*??
  • @Raca 是的,我刚刚找到了 Traverson - 它看起来很整洁。它仍然在下面执行三个 http 请求,不是吗?

标签: java spring spring-boot spring-data-jpa hateoas


【解决方案1】:

使用 HATEOAS 服务器可以通过提供的链接引导客户端。服务器和客户端之间的契约是链接的关系类型和媒体类型。如果资源处于启用或禁用编辑的状态,或者如果用户被授权对资源进行某些操作等,服务器可以通过提供或不提供相同资源表示上的链接来向客户端提供信息。服务器可以在不违反合同的情况下更改 URL。

【讨论】:

  • 我已经知道了。我的问题是:“如果您以编程方式访问服务器并且您已经知道目标 uri,这有什么好处?您仍然必须至少知道 'rel' 字符串。我只是不明白这对我有什么帮助
  • 如果您控制服务器和客户端,那么您知道某些资源的 URL,但您不知道服务器可以通过提供或不提供链接来提供的其他信息。如果服务器端超出您的控制范围,则资源 URL 可能会更改,这将破坏您的客户端。如果您需要性能优化,正如@haraldK 所写,“......从根(“全局”)端点直接公开指向“用户/经理”(以及所有其他常用资源)的链接。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 2014-11-28
  • 2013-04-14
  • 1970-01-01
相关资源
最近更新 更多