5

I'm using spring-data-common's PagedResourcesAssembler in my REST controller, and I was happy to see it even generates next/previous links in the response. However, in those cases where I have additional query parameters (besides page, size, sort), these are not included in the generated links. Can I somehow configure the assembler to include the parameters in the links?

Many thanks, Daniel

2 Answers 2

7

You need to build base link by yourself and pass it to "toResource" method of PagedResourcesAssembler.

@Controller
@RequestMapping(value = "/offer")
public class OfferController {

    private final OfferService offerService;

    private final OfferAssembler offerAssembler;

    @Autowired
    public OfferController(final OfferService offerService, OfferAssembler offerAssembler) {

        this.offerService= checkNotNull(offerService);
        this.offerAssembler= checkNotNull(offerAssembler);
    }

    @RequestMapping(value = "/search/findById", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
    public ResponseEntity<PagedResources<OfferResource>> findOfferById(
            @RequestParam(value = "offerId") long offerId, Pageable pageable,
            PagedResourcesAssembler<OfferDetails> pagedResourcesAssembler) {
        Page<OfferDetails> page = service.findById(offerId, pageable);

        Link link = linkTo(methodOn(OfferController.class).findOfferById(offerId,
                pageable,
                pagedResourcesAssembler)).withSelfRel();
        PagedResources<OfferResource> resource = pagedResourcesAssembler.toResource(page, assembler, link);
        return new ResponseEntity<>(resource, HttpStatus.OK);
    }
}

As a result you will get:

http://[your host]/[your app context]/offer/search/findById?offerId=[some offer id]{&page,size,sort}
Sign up to request clarification or add additional context in comments.

2 Comments

I tried to use the same type of Link as you used in the answer, but it didn't work for me. This is what worked: Link link = new Link(entityLinks.linkFor(Inventory.class, "name","page","size","sort").toString() + "/search/categoryName{?name,page,size,sort}").withSelfRel(). I'm going to take another stab at it and see if I can get it to work like yours, but for now I'm happy that it's working.
Excellent thanks, but a few points. 1) you don't actually need the 'assembler' parameter in the .toResource call, you can just do it with the page and link. 2) The self link seems to not include the pagination params for some reason, which is a shame (@HatemJaber pointed this out I believe).
2

The following solution is based on the answer provided by @palisade, but addresses the problem of pagination parameters not appearing in the self link--a problem noted by two of the answer's commenters, and which I experienced myself.

By replacing palisade's link declaration...

Link link = linkTo(methodOn(OfferController.class).findOfferById(offerId,
                pageable,
                pagedResourcesAssembler)).withSelfRel();

...with the following...

Link link = new Link(ServletUriComponentsBuilder.fromCurrentRequest().build()
               .toUriString())
               .withSelfRel();

...I'm getting page links that look like this:

{
    "links": [
        {
            "rel": "first",
            "href": "http://[your host]/[your app context]/offer/search/findById?offerId=[some offer id]&page=0&size=1"
        },
        {
            "rel": "prev",
            "href": "http://[your host]/[your app context]/offer/search/findById?offerId=[some offer id]&page=2&size=1"
        },
        {
            "rel": "self",
            "href": "http://[your host]/[your app context]/offer/search/findById?offerId=[some offer id]&page=3&size=1"
        },
        {
            "rel": "next",
            "href": "http://[your host]/[your app context]/offer/search/findById?offerId=[some offer id]&page=4&size=1"
        },
        {
            "rel": "last",
            "href": "http://[your host]/[your app context]/offer/search/findById?offerId=[some offer id]&page=6&size=1"
        }
    ],
    "content": [
        {
            ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.