Spring REST和HAL浏览器

2023/05/18

1. 概述

在本教程中,我们介绍HAL浏览器是什么,以及它有什么用。然后,我们使用Spring构建一个包含一些端点的简单REST API,并使用一些测试数据初始化数据库。

最后,使用HAL浏览器,我们将探索我们的REST API并发现如何遍历其中包含的数据。

2. HAL和HAL浏览器

JSON超文本应用程序语言(HAL)是一种简单的格式,它提供了一种一致且简单的方法来在我们的API中的资源之间进行超链接。在我们的REST API中包含HAL使其对用户来说更容易探索,并且本质上是自我记录的。

它的工作原理是返回JSON格式的数据,其中概述了有关API的相关信息。

HAL模型围绕两个简单的概念展开

资源,其中包含:

  • 相关URI的链接
  • 嵌入式资源
  • 状态

链接:

  • 目标URI
  • 与链接的关系
  • 其他一些可选属性,可帮助折旧、内容协商等

HAL浏览器是由开发HAL的同一个人创建的,并提供浏览器内GUI来遍历你的REST API

现在,我们将构建一个简单的REST API,插入HAL浏览器并探索这些功能。

3. 依赖关系

下面是将HAL浏览器集成到我们的REST API中所需的唯一依赖项。

首先,基于Maven项目的[依赖](https://search.maven.org/classic/#search gav 1 g%3A”org.springframework.data” AND a%3A”spring-data-rest-hal-browser”)为:
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-rest-hal-explorer</artifactId>
    <version>3.4.1.RELEASE</version>
</dependency>

如果你使用Gradle进行构建,则可以将以下行添加到你的build.gradle文件中:

implementation group: 'org.springframework.data', name: 'spring-data-rest-hal-explorer', version: '3.4.1.RELEASE'

4. 构建一个简单的REST API

4.1 简单数据模型

在我们的示例中,我们将设置一个简单的REST API来访问不同的Book对象。

在下面,我们定义了一个简单的Book实体,其中包含适当的JPA注解,以便我们可以使用Hibernate持久化数据:

@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @NotNull
    @Column(columnDefinition = "VARCHAR", length = 100)
    private String title;

    @NotNull
    @Column(columnDefinition = "VARCHAR", length = 100)
    private String author;

    @Column(columnDefinition = "VARCHAR", length = 1000)
    private String blurb;

    private int pages;

    // usual getters, setters and constructors
}

4.2 Repository

接下来,我们需要一些端点。为此,我们可以利用PagingAndSortingRepository并指定我们要从Book实体获取数据。

这个类提供了简单的CRUD功能,以及开箱即用的分页和排序功能

@Repository
public interface BookRepository extends PagingAndSortingRepository<Book, Long> {

    @RestResource(rel = "title-contains", path="title-contains")
    Page<Book> findByTitleContaining(@Param("query") String query, Pageable page);

    @RestResource(rel = "author-contains", path="author-contains", exported = false)
    Page<Book> findByAuthorContaining(@Param("query") String query, Pageable page);
}

我们通过添加两个新端点扩展了Repository:

  • findByTitleContaining:返回包含标题中包含的查询的Book
  • findByAuthorContaining:从数据库中返回书籍作者包含查询的Book

请注意,我们的第二个端点包含export = false属性。此属性停止为此端点生成HAL链接,并且将无法通过HAL浏览器使用。

最后,我们在Spring启动时通过定义一个实现ApplicationRunner接口的类来加载我们的数据。

5. 安装HAL浏览器

在使用Spring构建REST API时,HAL浏览器的设置非常简单。只要我们添加了依赖项,Spring就会自动配置浏览器,并通过默认端点使其可用。

我们现在需要做的就是运行并切换到浏览器。HAL浏览器将在http://localhost:8080/上可用

6. 使用HAL浏览器探索我们的REST API

HAL浏览器分为两部分:资源管理器和检查器

6.1 HAL浏览器

听起来,资源管理器致力于探索API中与当前端点相关的新部分。它包含一个搜索栏,以及用于显示当前端点的自定义请求标头和属性的文本框。

在这些下面,我们有链接部分和一个可点击的嵌入式资源列表。

6.2 使用链接

如果我们导航到/books端点,我们可以查看现有链接:

链接-1

这些链接是从相邻部分中的HAL生成的:

"_links": {
    "first": {
      "href": "http://localhost:8080/books?page=0&size=20"
    },
    "self": {
      "href": "http://localhost:8080/books{?page,size,sort}",
      "templated": true
    },
    "next": {
      "href": "http://localhost:8080/books?page=1&size=20"
    },
    "last": {
      "href": "http://localhost:8080/books?page=4&size=20"
    },
    "profile": {
      "href": "http://localhost:8080/profile/books"
    },
    "search": {
      "href": "http://localhost:8080/books/search"
    }
},

如果我们移动到search端点,我们还可以查看我们使用PagingAndSortingRepository创建的自定义端点:

{
    "_links": {
        "title-contains": {
            "href": "http://localhost:8080/books/search/title-contains{?query,page,size,sort}",
            "templated": true
        },
        "self": {
            "href": "http://localhost:8080/books/search"
        }
    }
}

上面的HAL显示了我们的title-contains端点显示了合适的搜索条件。请注意author-contains端点是如何丢失的,因为我们定义了它不应该被导出。

6.3 查看嵌入式资源

嵌入式资源在我们的/books端点上显示单个Book记录的详细信息。每个资源还包含自己的属性和链接部分:

嵌入 2

6.4 使用表单

链接部分中GET列中的问号按钮表示可以使用表单模式输入自定义搜索条件。

这是我们的title-contains端点的形式:

HAL浏览器选择表

我们的自定义URI返回20个Book对象的第一页,其中标题包含单词“Java”。

6.5 Hal检查器

检查器构成浏览器的右侧,包含响应标头和响应正文。此HAL数据用于呈现我们在本教程前面看到的链接和嵌入式资源。

7. 总结

在本文中,我们总结了HAL是什么、它有什么用以及为什么它可以帮助我们创建卓越的自文档化REST API。

我们使用Spring构建了一个简单的REST API,它实现了PagingAndSortingRepository,并定义了我们自己的端点。我们还了解了如何从HAL浏览器中排除某些端点。

在定义了我们的API之后,我们初始化了一些测试数据,并在HAL浏览器的帮助下对其进行了详细探索。我们看到了HAL浏览器的结构,以及允许我们逐步执行API和探索其数据的UI控件。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章