Spring Data Rest / Spring Hateoas User Controller - PersistentEntityResourceAssembler

I am trying to add additional business logic to automatically generated endpoints from RepositoryRestResource. See code below:

Resource:

@RepositoryRestResource(collectionResourceRel="event", path="event") public interface EventRepository extends PagingAndSortingRepository<Event, Long> { } 

Controller:

 @RepositoryRestController @RequestMapping(value = "/event") public class EventController { @Autowired private EventRepository eventRepository; @Autowired private PagedResourcesAssembler<Event> pagedResourcesAssembler; @RequestMapping(method = RequestMethod.GET, value = "") @ResponseBody public PagedResources<PersistentEntityResource> getEvents(Pageable pageable, PersistentEntityResourceAssembler persistentEntityResourceAssembler) { Page<Event> events = eventRepository.findAll(pageable); return pagedResourcesAssembler.toResource(events, persistentEntityResourceAssembler); } } 

I reviewed the following two stackoverflow articles:

It seems to me that I'm close, but the problem that I encountered is the following:

 return pagedResourcesAssembler.toResource(events, persistentEntityResourceAssembler); 

returns an error message:

 "The method toResource(Page<Event>, Link) in the type PagedResourcesAssembler<Event> is not applicable for the arguments (Page<Event>, PersistentEntityResourceAssembler)". 

The toResource method has a method signature that accepts ResourceAssembler, but I'm not sure how to implement it correctly, and I cannot find documentation on this.

Thanks in advance - Brian

Edit

My problem was that I decided to override the controller methods created automatically from the @RepositoryRestResource annotation without creating my own resource and resource assembler. After creating the resource and resource assembler, I was able to add my business logic to the endpoint.

Resource:

 public class EventResource extends ResourceSupport { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } 

Assembler Resources:

 @Component public class EventResourceAssembler extends ResourceAssemblerSupport<Event, EventResource> { public EventResourceAssembler() { super(EventController.class, EventResource.class); } @Override public EventResource toResource(Event entity) { EventResource eventResource = createResourceWithId(entity.getId(), entity); eventResource.setName(entity.getName()); return eventResource; } } 

Controller updated:

 @RepositoryRestController @RequestMapping(value = "/event") public class EventController { @Autowired private EventRepository eventRepository; @Autowired private EventResourceAssembler eventResourceAssembler; @Autowired private PagedResourcesAssembler<Event> pageAssembler; @RequestMapping(method = RequestMethod.GET, value = "") @ResponseBody public PagedResources<EventResource> getEvents(Pageable pageable) { Page<Event> events = eventRepository.findAll(pageable); // business logic return pageAssembler.toResource(events, eventResourceAssembler); } } 

What I don't like about this is that it seems to be pursuing the goal of creating a RepositoryRestResource. Another approach would be to use event handlers that will be called before and / or after the create, save and delete operations.

 @RepositoryEventHandler(Event.class) public class EventRepositoryEventHandler { @HandleBeforeCreate private void handleEventCreate(Event event) { System.out.println("1"); } } 

It seems that there were no events for findAll or findOne operations. In any case, both of these approaches seem to solve my problem of extending the automatically created controller methods from RepositoryRestResource.

+5
source share
1 answer

This requires a PagedResourcesAssembler, Spring will introduce one for you if you ask.

 public PagedResources<Foo> get(Pageable page, PagedResourcesAssembler<Foo> assembler) { // ... } 

In this case, the Foo resource. It seems that in your case the resource you are trying to return is Event . If so, I expect your code to look something like this:

 private ResourceAssembler<Event> eventAssembler = ...; public PagedResources<Event> get(Pageable page, PagedResourcesAssembler<Event> pageAssembler) { Event event = ...; return eventAssembler.toResource(event, pageAssembler); } 

You provide a ResourceAssembler<Event> that tells Spring how to turn an Event into a Resource . Spring injects the PagedResourcesAssembler<Event> into your controller method to handle page links. Combine them by calling toResource and passing in a nested pageAssembler .

The end result can be returned simply as a body, as indicated above. You can also use things like HttpEntity to get more control over status codes and headers.

Note. ResourceAssembler that you provide can literally be as simple as moving a resource, such as an Event , with a Resource object. Generally, you will want to add any relevant links.

+1
source

Source: https://habr.com/ru/post/1235380/


All Articles