I'm using the latest of Spring REST and HATEOAS trying to expose a link to a search endpoint.
Here is the resource assembler:
@Component
public class AdminResourceAssembler extends ResourceAssemblerSupport<Admin, AdminResource> {
public AdminResourceAssembler() {
super(AdminController.class, AdminResource.class);
}
public AdminResource toResource(Admin admin) {
AdminResource adminResource = createResourceWithId(admin.getId(), admin);
BeanUtils.copyProperties(admin, adminResource);
adminResource.add(linkTo(AdminController.class).slash(admin.getId()).slash("module").withRel("module"));
return adminResource;
}
}
Here is the end point controller:
@RequestMapping(value = UriMappingConstants.PATH_SEPARATOR + UriMappingConstants.SEARCH, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<PagedResources<AdminResource>> search(@RequestParam(value = "searchTerm", required = true) String searchTerm, @PageableDefault Pageable pageable, PagedResourcesAssembler<Admin> pagedResourcesAssembler, UriComponentsBuilder builder) {
HttpHeaders responseHeaders = new HttpHeaders();
Pageable pageRequest = buildPageRequest(pageable.getPageNumber(), pageable.getPageSize());
Page<Admin> searchedAdmins = adminService.search(searchTerm, pageRequest);
responseHeaders.setLocation(builder.path(UriMappingConstants.PATH_SEPARATOR + UriMappingConstants.ADMINS + UriMappingConstants.PATH_SEPARATOR + "search").queryParam("searchTerm", searchTerm).queryParam("page", pageable.getPageNumber()).queryParam("size", pageable.getPageSize()).buildAndExpand(searchTerm).toUri());
PagedResources<AdminResource> adminPagedResources = pagedResourcesAssembler.toResource(searchedAdmins, adminResourceAssembler);
return new ResponseEntity<PagedResources<AdminResource>>(adminPagedResources, responseHeaders, HttpStatus.OK);
}
private Pageable buildPageRequest(int pageIndex, int pageSize) {
Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC, "lastname"), new Sort.Order(Sort.Direction.ASC, "firstname"));
return new PageRequest(pageIndex, pageSize, sort);
}
First, I'm not sure if I should call in the buildPageRequest method and simply pass in the original pageable to the search service.
The problem I have is two fold:
The published link in the response is missing the searchTerm parameter:
{"rel":"self","href":"http://localhost:8080/nitro-project-rest/admins/search{?page,size,sort}
I would expect it to be like:
{"rel":"self","href":"http://localhost:8080/nitro-project-rest/admins/search{?searchTerm,page,size,sort}
But again, as a newbie I don't know for sure.
And the controller always fetches the first page of the 10 items, ignoring the page number and size arguments I give in the request:
curl -H "Accept:application/json" --user joethebouncer:mignet http://localhost:8080/nitro-project-rest/admins/search?searchTerm=irstna&page=3&size=5
I guess I'm not too far from a asolution, but I don't even know exactly what the exposed link should look like.
Any directions would be very nice :-)
EDIT: Added information
The pageable configuration:
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
argumentResolvers.add(resolver);
super.addArgumentResolvers(argumentResolvers);
}
The service is simply a wrap around the repository:
public Page<Admin> search(String searchTerm, Pageable page) {
return adminRepository.search(searchTerm, page);
}
which is an interface:
@Query("SELECT a FROM Admin a WHERE LOWER(a.firstname) LIKE LOWER(CONCAT('%', :searchTerm, '%')) OR LOWER(a.lastname) LIKE LOWER(CONCAT('%', :searchTerm, '%')) OR LOWER(a.email) LIKE LOWER(CONCAT('%', :searchTerm, '%')) OR LOWER(a.login) LIKE LOWER(CONCAT('%', :searchTerm, '%')) ORDER BY a.lastname ASC, a.firstname ASC") public
Page search(@Param("searchTerm") String searchTerm, Pageable page);
The database is H2 fronted by JPA and the console shows:
One can see that the offset is missing...
select admin0_.id as id1_1_, admin0_.version as version2_1_, admin0_.email as email3_1_, admin0_.firstname as firstnam4_1_, admin0_.lastname as lastname5_1_, admin0_.login as login6_1_, admin0_.password as password7_1_, admin0_.password_salt as password8_1_, admin0_.post_login_url as post_log9_1_ from admin admin0_ where lower(admin0_.firstname) like lower(('%'||'irstn'||'%')) order by admin0_.lastname ASC, admin0_.firstname ASC, admin0_.lastname asc, admin0_.firstname asc limit 10
Kind Regards,
Stephane Eybert