0

In the Spring Data JPA documentation it explains how to generate links using PagedResourcesAssembler. The documentation makes reference to a toResources() method but as far as I can see that method does not exist. I have successfully generated links for the collection of resources but I can't figure out how to generate links for the sub resources.

Here is my controller:

public HttpEntity<PagedResources<Party>> search(@RequestBody PartySearchRequest request,
                                                    Pageable pageable, PagedResourcesAssembler<Party> assembler ) {

        Map<String,String> searchFilters = RequestValidator.validateContractSearchFilters(request);

        Page<Party> parties = repository.findByFirstNameOrLastName(searchFilters.get("firstName"), searchFilters.get("lastName"), pageable);

        return new ResponseEntity(assembler.toResource(parties), HttpStatus.OK);

    }

This produces the following JSON:

{
  "_embedded": {
    "partyList": [
      {
        "firstNm": "John",
        "lastNm": "Doe",
      },
      {
        "firstNm": "Bob",
        "lastNm": "Smith",
       }
        ],
      }
    ]
  },
  "_links": {
    "first": {
      "href": "http://localhost:8080/v1/party/search?page=0&size=2"
    },
    "self": {
      "href": "http://localhost:8080/v1/party/search?page=0&size=2"
    },
    "next": {
      "href": "http://localhost:8080/v1/party/search?page=1&size=2"
    },
    "last": {
      "href": "http://localhost:8080/v1/party/search?page=7&size=2"
    }
  },
  "page": {
    "size": 2,
    "totalElements": 16,
    "totalPages": 8,
    "number": 0
  }
}

As you can see I get links for the entire parties search but not for the individual party objects. (I think my question is similar to this question: How to add HATEOAS links in a sub resource) but I wasn't quite sure so I posted my own.

Any help would be greatly appreciated! Thank you!

ejgreenwald
  • 172
  • 4
  • 16

1 Answers1

1

You need a reference to your class that extends ResourceAssemblerSupport.

This should work, changing myResourceAssembler to whatever your class is:

In your controller:

private final MyResourceAssembler myResourceAssembler;

public MyController(MyResourceAssembler myResourceAssembler) {
   this.myResourceAssembler = myResourceAssembler;
}

public HttpEntity<PagedResources<Party>> search(@RequestBody PartySearchRequest request,
                                                Pageable pageable, PagedResourcesAssembler<Party> assembler ) {

    Map<String,String> searchFilters = RequestValidator.validateContractSearchFilters(request);

    Page<Party> parties = repository.findByFirstNameOrLastName(searchFilters.get("firstName"), searchFilters.get("lastName"), pageable);

    Link selfLink = linkTo(methodOn(this.getClass().view(pageable, null)).withSelfRel();

    return new ResponseEntity(assembler.toResource(parties, myResourceAssembler, selfLink), HttpStatus.OK);

}

And, if you don't want the selfLink:

return new ResponseEntity(assembler.toResource(parties, myResourceAssembler), HttpStatus.OK);

References

Brian
  • 4,921
  • 3
  • 20
  • 29
  • Thank you. I created a PartyResourceAssembler extends ResourceAssemblerSupport but I'm having issues injecting it. I'm using spring-boot. Any quick advice? Thank you – ejgreenwald Aug 07 '17 at 20:12
  • 1
    Is it annotated with `@Component`? – Brian Aug 07 '17 at 20:14
  • Silly mistake :) Now it autowires. So if I understand correctly the ResourceAssemblerSupport takes care of each of the individual resource links and the PagedResourcesAssembler takes care of the resource as a whole? – ejgreenwald Aug 07 '17 at 20:25
  • 1
    Correct, the resource you are returning is a collection of resources. The collection is in itself a resource, and it contains the _embedded with the nested collection(s). Each nested collection item is an individual resource with it's own set of link(s). The PagedResourcesAssembler handles things like prev/next links. – Brian Aug 07 '17 at 20:30
  • Yup. I got everything working. The only thing is that now I have to create a resource for each entity and then an assembler for each resource. Lots of extra classes... Any advice on how to not have to create an assembler and resource for each entity? Thanks for all your help. – ejgreenwald Aug 07 '17 at 21:28
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/151316/discussion-between-ejgreenwald-and-brian). – ejgreenwald Aug 07 '17 at 21:28
  • 2 out of the 3 links are dead. – code Dec 21 '20 at 07:38