Spring HATEOAS Resource Assembler and Resource Links with many variables
hateoas, java, rest, spring, spring-hateoas
Solution
@Override
public RibResource toResource(Rib rib) {
return createResourceWithId(rib.getId(), rib);
}
`createResourceWithId()` internally creates a self link based on the controller's URL. In your case that contains the placeholder `{idInt}` so you would have to provide a parameter for that:
CustomUserDetails user = CurrentUserUtils.getCurrentUser();
return createResourceWithId(rib.getId(), rib, user.getIdInt());
The better choice would be not to call `createResourceWithId()` at all. Just move everything you now have in `instantiateResource()` to `toResource()`.
Problem
I'm working on REST API with Spring HATEOAS and the Spring stack, and i have some problems with links into resources. Here is my code : the Controller : ``` @RestController @RequestMapping("/apporteurs/{idInt}/ribs") public class RibController { @Autowired private RibResourceAssembler ribResourceAssembler; @Autowired private RibRepository ribRepository; /** * Methode GET permettant d'obtenir un Rib par son ID * * @param idRib ID du Rib * @return RibResource */ @RequestMapping(value = "/{idRib}", method = RequestMethod.GET) @ResponseBody public RibResource getRibById(@PathVariable Long idInt, @PathVariable Long idRib) { CurrentUserUtils.checkAuthorizationByApporteur(idInt); return ribResourceAssembler.toResource(ribRepository.getRibById(idRib)); } } ``` The Assembler : ``` @Component public class RibResourceAssembler extends ResourceAssemblerSupport<Rib, RibResource> { public static final long TMP_IDS = 1234L; @Autowired private RibResourceMapper ribResourceMapper; public RibResourceAssembler() { super(RibController.class, RibResource.class); } @Override public RibResource toResource(Rib rib) { return createResourceWithId(rib.getId(), rib); } /** * TODO : mettre le lien vers l'editique Mandat * * @param rib Rib à instancier en Resource. * @return RibResource */ @Override protected RibResource instantiateResource(Rib rib) { RibResource ribResource = ribResourceMapper.fromRib(rib, rib.getLastMandat()); ribResource.removeLinks(); CustomUserDetails user = CurrentUserUtils.getCurrentUser(); UriComponentsBuilder uriBuilderMandat = linkTo(RibController.class).toUriComponentsBuilder(); String uri = uriBuilderMandat.path("/{idRib}/mandats/{idMandat}").buildAndExpand(user.getIdInt(), rib.getId(), TMP_IDS).toUriString(); Link linkEditiqueMandat = new Link(uri).withRel("editiqueMandat"); UriComponentsBuilder uriBuilderRib = linkTo(RibController.class).toUriComponentsBuilder(); String uriSelf = uriBuilderRib.path("/{idRib}").buildAndExpand(user.getIdInt(), rib.getId()).toUriString(); Link linkUriSelf = new Link(uriSelf).withSelfRel(); ribResource.add(linkEditiqueMandat); ribResource.add(linkUriSelf); return ribResource; } } ``` The Resource : ``` public class RibResource extends ResourceSupport { private Long idRib; private String rum; private String iban; private String libelle; private String dateFin; private String dateCreation; private String dateModification; private String codeOperateurCreation; private String dateRegulationMandat; private boolean actif; private boolean reactivable; private CodeValueResource modeReglement; /*Gzetter & setters, etc*/ } ``` As you can see, my controller have some parameters in the URI : idInt and idRib. So for make a SelfLink, i have to know this parameters for make something like "/apporteurs/1234/ribs/1234", but i think the Assembler want only one parameter, and a "simple" URI. I have this stack trace : ``` 2014-11-25 12:02:09.365 ERROR 20860 --- [nio-9080-exec-1] w.s.m.m.a.ResponseEntityExceptionHandler : Not enough variable values available to expand 'idInt' ``` So i'm looking for an elegant solution to do this, because i didn't find anything ^^ I saw something with ResourceProcessor, but i'm not using Spring Data Rest. Can you help me ? Thank you in advance ;) EDIT : The result should be : ``` _links": { "editiqueMandat": { "href": "http://localhost:9080/apporteurs/6797/mandats/5822" }, "self": { "href": "http://localhost:9080/apporteurs/6797/ribs/1234" } } ```