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);
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.