Spring HATEOAS build link to paged resource
Asked Answered
I

1

10

I have a controller with method, which returns PagedResource, which looks like this:

@RequestMapping(value = "search/within", method = RequestMethod.POST)
public @ResponseBody PagedResources within(@RequestBody GeoJsonBody body,
                                           Pageable pageable, PersistentEntityResourceAssembler asm) {

    //  GET PAGE

    return pagedResourcesAssembler.toResource(page, asm);
}

Now, I want to add that method as a link to the root resource, so I do the following:

public RepositoryLinksResource process(RepositoryLinksResource repositoryLinksResource) {
    repositoryLinksResource.add(linkTo(methodOn(ShipController.class).within(null, null, null)).withRel("within"));

    return repositoryLinksResource;
}

Which works and I get my link, however it add that link without pagination parameters. So it look like this:

    "within": {
        "href": "http://127.0.0.1:5000/search/within"
    },

and I want to turn it into:

    "within": {
        "href": "http://127.0.0.1:5000/search/within{?page, size}"
    },

This previous question on stackoverflow suggests that after fixing the corresponding issue on GitHub it should work by default, however, it doesn't.

What am I doing wrong ?

Iconium answered 26/7, 2018 at 15:46 Comment(0)
N
6

Automatic Creation of Paginated Links with PagedResourcesAssembler

I had success using PagedResourcesAssembler. Let's say your entity is called MyEntity. Your within method should return HttpEntity<PagedResources<MyEntity>>.

Your within method should look something similar to the example shown below.

@RequestMapping(value = "search/within", method = RequestMethod.POST)
@ResponseBody 
public HttpEntity<PagedResources<MyEntity>> 
    within(@RequestBody GeoJsonBody body,Pageable pageable, 
           PagedResourcesAssembler assembler) {
    //  GET PAGE
    Page<MyEntity> page = callToSomeMethod(pageable);

    return new ResponseEntity<>(assembler.toResource(page), HttpStatus.OK);
}

Here is a simple example. In this example, the response looked like the one shown below,

{
    "_embedded": {
    "bookList": [
      {
        "id": "df3372ef-a0a2-4569-982a-78c708d1f609",
        "title": "Tales of Terror",
        "author": "Edgar Allan Poe"
      }
    ]
  },
  "_links": {
    "self": {
      "href": "http://localhost:8080/books?page=0&size=20"
    }
  },
  "page": {
    "size": 20,
    "totalElements": 1,
    "totalPages": 1,
    "number": 0
  }
}

Manual Creation of Paginated Self Link

If you're interested in creating the paginated link manually, here's the code snippet you can use,

Page<MyEntity> page = callToSomeMethod(pageable);

ControllerLinkBuilder ctrlBldr =
    linkTo(methodOn(ShipController.class).within(body, pageable, asm));
UriComponentsBuilder builder = ctrlBldr.toUriComponentsBuilder();

int pageNumber = page.getPageable().getPageNumber();
int pageSize = page.getPageable().getPageSize();
int maxPageSize = 2000;

builder.replaceQueryParam("page", pageNumber);
builder.replaceQueryParam("size", pageSize <= maxPageSize ? 
    page.getPageable().getPageSize() : maxPageSize);

Link selfLink =
    new Link(new UriTemplate(builder.build().toString()), "self");
Naoise answered 5/8, 2018 at 6:32 Comment(5)
So you tested that if you change the return type that way, the link builder will create a link with paging params as template parameters?Camera
@IndraBasak thanks for the answer. unfortunately it doesn't seem to help me. Could you show the way you've created that link ? i.e resource.add(...) callCabriolet
@IndraBasak that's a bit different, though. You create automatic self link, where i want a link to the method from different request. Returning ResponseEntitiry still doesn't help, the link genereted doesn't have any parametersCabriolet
@IndraBasak I did. there's no manual link creation, only automatic with PagedResourseAssembler.Cabriolet
you made my day! Having hard time how to link pageable object as url. your builder .replaceQueryParam logic helpedKery

© 2022 - 2024 — McMap. All rights reserved.