Introduction

HATEOAS is a principle for implementing the REST specification. By following the HATEOAS specification, various problems of our actual code implementation can be solved. Spring is the most popular framework for java
Of course, the integration of HATEOAS will not be absent.

This article will explain how to use HATEOAS in SpringBoot through a specific example.

Our goal

In HATEOAS rules, the returned data will be linked. Let's take the familiar Book as an example to show this HATEOAS, first create a Book entity:

 @Data
@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
}

We hope to get the detailed data of Book through the following link:

 GET /book/1

The returned data is as follows:

 {
    "content": {
        "id": 1,
        "title": "The Hobbit"
    },
    "_links": {
        "self": {
            "href": "http://localhost:8080/book/1"
        }
    }
}

It can be seen that in the returned data, in addition to the book information contained in the content, there is also a _links attribute that represents resource links related to the Book.

Build Entity and Repository

Before doing any data, we need to build the corresponding data, that is, the entity and the corresponding data operation. For the sake of simplicity, we use the H2 in-memory database.

We need to configure the following in application.properties:

 spring.jpa.hibernate.ddl-auto=validate

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

Then configure the corresponding repository:

 public interface BookRepository extends CrudRepository<Book, Long> {
    long deleteByTitle(String title);

    @Modifying
    @Query("delete from Book b where b.title=:title")
    void deleteBooks(@Param("title") String title);
}

At the same time, you need to place schema.sql for creating table and data.sql for inserting data in resources. In this way, the corresponding data can be automatically created when the program starts.

Build HATEOAS-related RepresentationModel

If you want to do it yourself, you can also implement the operation of adding links, but this is too complicated. Fortunately, we have Spring. To use HATEOAS with Spring, the following configuration is required:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-hateoas</artifactId>
        </dependency>

If we want to build HATEOAS for Book, we can build a class that inherits RepresentationModel:

 public class BookModel extends RepresentationModel<BookModel> {

    private final Book content;

    @JsonCreator
    public BookModel(@JsonProperty("content") Book content) {
        this.content = content;
    }

    public Book getContent() {
        return content;
    }
}

In the above example, we encapsulated a Book object with RepresentationModel and set it as the content property of json.

Build the Controller

With the RepresentationModel, we can use it to build the HATEOAS response.

Let's look at the following example:

 @RequestMapping("/book/{id}")
    public HttpEntity<Book> getBook(@PathVariable("id") Long id) {
        Book book= bookRepository.findById(id).get();
        BookModel bookModel = new BookModel(book);
        bookModel.add(linkTo(methodOn(BookController.class).getBook(id)).withSelfRel());
        return new ResponseEntity(bookModel, HttpStatus.OK);
    }

In the above example, we used @RequestMapping to construct an HTTP request to find the corresponding Book data from the database by passing in the id of the book.

Then pass it into the BookModel and build the RepresentationModel. At this time, the object can be returned directly. But we also need to add some links to it.

We use bookModel.add to add the corresponding link. And use the linkTo method to generate the corresponding link.

Finally, the RepresentationModel is returned.

When we request /book/1, we will get the json value we want to get at the front. Is it easy to use HATEOAS?

Meaning of HATEOAS

HATEOAS has a corresponding resource link, and through a resource, you can get other resources that can be accessed from this resource, just like when you access a page, you can access other pages through this page.

So the significance of HATEOAS is that we only need to access one resource to traverse all resources.

We experience the access to resources through testing.

First, we directly access the resource /book/1 to confirm the result:

 @Test
    void envEndpointNotHidden() throws Exception {
        mockMvc.perform(get("/book/1"))
                .andExpect(jsonPath("$.content.title").value("The Hobbit"));
    }

Then use the Traverson class provided by Spring HATEOAS to perform link traversal:

 @Test
    void envEndpointNotHidden() throws Exception {
        Traverson traverson = new Traverson(new URI("http://localhost:" + this.port + "/book/1"), MediaTypes.HAL_JSON);
        String bookTitle = traverson.follow("self").toObject("$.content.title");
        assertThat(bookTitle).isEqualTo("The Hobbit");
    }

Summarize

Very good, we can already use the basic HATEOAS, the examples in this article can refer to:

learn-springboot2


flydean
890 声望433 粉丝

欢迎访问我的个人网站:www.flydean.com