spring-projects / spring-projects/spring-data-rest
Cannot create customs links for ResourceProcessor<PagedResources<...>> [DATAREST-375]
Open
@odrotbohm is already working on this.
Since Dec 31, 2020.
type: bug
- Dominant language
- Java
- Stars
- 958
- Forks
- 568
- PR merge metrics
- No merged PRs in 30d
Description
Manuel Lara Caro opened DATAREST-375 and commented
I've a Controller that exposes a several custom search based in Specification and I want to create the search link of HATEOAS, but it never run:
@RestController
@RequestMapping(value = "/seasons/search")
@ExposesResourceFor(Season.class)
//public class SeasonRepositoryCustomRest implements ResourceProcessor<RepositoryLinksResource> {
//public class SeasonRepositoryCustomRest implements ResourceProcessor<Resource<Season>> {
public class SeasonRepositoryCustomRest implements ResourceProcessor<PagedResources<Resource<Season>>> {
@RequestMapping(value = "/findByFootballer", method = RequestMethod.GET, produces = "application/json")
public HttpEntity<PagedResources<Resource<Season>>> findByFootballer(@RequestParam(value = "id") final long id,
Pageable pageable, PagedResourcesAssembler<Season> assembler) {
Page<Season> page = repository.findAll(new Specification<Season>() {
@Override
public Predicate toPredicate(Root<Season> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
query.groupBy(root.<String>get("name"));
return builder.equal(root.joinSet("statistics", JoinType.INNER)
.<FootballPlayer>get("footballer").<Long>get("id"), id);
}
}, pageable);
PagedResources<Resource<Season>> body = assembler.toResource(page);
return new ResponseEntity<PagedResources<Resource<Season>>>(body, HttpStatus.OK);
}
@Override
public PagedResources<Resource<Season>> process(PagedResources<Resource<Season>> resource) {
resource.add(linkTo(getClass()).withRel("search"));
return resource;
}
}
I've been debugging the Spring code and I've seen that if you use pagination it isn't possible:
/**
* Returns whether the given {@link Resources} instance matches the given {@link TypeInformation}. We predict this
* by inspecting the first element of the content of the {@link Resources}.
*
* @param resources the {@link Resources} to inspect.
* @param target that target {@link TypeInformation}.
* @return
*/
private static boolean isValueTypeMatch(Resources<?> resources, TypeInformation<?> target) {
if (resources == null || !Resources.class.equals(resources.getClass())) {
return false;
}
Collection<?> content = resources.getContent();
if (content.isEmpty()) {
return false;
}
Object element = content.iterator().next();
if (!(element instanceof Resource)) {
return false;
}
TypeInformation<?> resourceTypeInformation = target.getSuperTypeInformation(Resources.class).getComponentType();
return ResourceProcessorWrapper.isValueTypeMatch((Resource<?>) element, resourceTypeInformation);
}
No further details from DATAREST-375
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.