SpringBoot 2 to build REST services-simplify the link creation process

Have we noticed duplication when creating a single employee link? The code that provides a single link to the employee and a link to the "employee" of the aggregate root is shown twice. If that caught our attention, that's good! There is a solution.

In short, we need to define a to Employeeconvert the object to EntityModel<Employee>object functions. While we can easily write their own method, but in the realization of Spring HATEOAS RepresentationModelAssemberthere will be many benefits of the process interface.

evolution/src/main/java/payroll/EmployeeResourceAssembler.java

package payroll;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;

import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.RepresentationModelAssembler;
import org.springframework.stereotype.Component;

@Component
class EmployeeModelAssembler implements RepresentationModelAssembler<Employee, EntityModel<Employee>> {

  @Override
  public EntityModel<Employee> toModel(Employee employee) {

    return new EntityModel<>(employee,
      linkTo(methodOn(EmployeeController.class).one(employee.getId())).withSelfRel(),
      linkTo(methodOn(EmployeeController.class).all()).withRel("employees"));
  }
}

The interface has a simple method: toModel(). It is based on converting non-resource objects ( Employee) to resource-based objects ( EntityModel<Employee>).

All the code we saw in the controller before can be moved into this class. By applying the Spring framework @Component, this component will be created automatically when the application starts.

Spring HATEOAS is the abstract base class for all resources RepresentationModel. But for the sake of simplicity, the tutorial is recommended EntityModel<T>as our mechanism to easily wrap all POJO as a resource.

To use the assembler and need to be injected into EmployeeControllerthe constructor can be changed.

Inject EmployeeResourceAssembler into the controller.

@RestController
class EmployeeController {

  private final EmployeeRepository repository;

  private final EmployeeModelAssembler assembler;

  EmployeeController(EmployeeRepository repository,
             EmployeeModelAssembler assembler) {

    this.repository = repository;
    this.assembler = assembler;
  }

  ...

}

Here, we can use it in the single employee method:

Use the assembler to get a single resource.

@GetMapping("/employees/{id}")
EntityModel<Employee> one(@PathVariable Long id) {

  Employee employee = repository.findById(id)
    .orElseThrow(() -> new EmployeeNotFoundException(id));

  return assembler.toModel(employee);
}

This code is almost identical, except that we are not here to create EntityModel<Employee>an example, but it is entrusted to the assembler. Maybe it doesn't look much?

Applying the same content in the aggregate root controller method is even more impressive:

Use the assembler to get the aggregate root resource.

@GetMapping("/employees")
CollectionModel<EntityModel<Employee>> all() {

  List<EntityModel<Employee>> employees = repository.findAll().stream()
    .map(assembler::toModel)
    .collect(Collectors.toList());

  return new CollectionModel<>(employees,
    linkTo(methodOn(EmployeeController.class).all()).withSelfRel());
}

Again, the code is almost the same, but we can all EntityModel<Employee>create logical replaced map(assembler::toModel). With Java 8 method references, it is very easy to insert and simplify our controller.

The main goal of Spring HATEOAS is to make "The Right Thing ™" easy. In this case, hypermedia can be added to our server without hard-coding things.

At this stage, we have created a Spring MVC REST controller that can actually generate hypermedia-supported content! Clients that do not use HAL can ignore the extra bits when using pure data. Clients who know HAL can browse our authorized API.

But this is not the only way to build true RESTful services with Spring.

Published 232 original articles · Liked 14 · Visits 20,000+

Guess you like

Origin blog.csdn.net/stevenchen1989/article/details/105586569