How to add HATEOAS links in a sub resource
Asked Answered
S

1

1

I have a parent resource called the AdminResource and a child resource called the AdminModuleResource.

The resource of the parent is correctly fitted with HATEOAS links:

{
  "firstname" : "Stephane",
  "lastname" : "Eybert",
  "email" : "[email protected]",
  "password" : "e41de4c55873f9c000f4cdaac6efd3aa",
  "passwordSalt" : "7bc7bf5f94fef7c7106afe5c3a40a2",
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost/admins/3683"
  }, {
    "rel" : "modules",
    "href" : "http://localhost/admins/3683/modules"
  } ],
  "id" : 3683
}

The resource of the child is also correctly fitted with HATEOAS links:

{
  "module" : "BTS",
  "adminResource" : {
    "firstname" : "Stephane",
    "lastname" : "Eybert",
    "email" : "[email protected]",
    "password" : "e41de4c55873f9c000f4cdaac6efd3aa",
    "passwordSalt" : "7bc7bf5f94fef7c7106afe5c3a40a2",
    "links" : [ ],
    "id" : 3683
  },
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost/modules"
  } ],
  "id" : 1087
}

But its parent resource has lost its links.

For now, when inside my child admin module resource, the parent admin resource does not have its links. Indeed the toResource method of the assembler only provides the links for the child admin module resource.

public AdminModuleResource toResource(AdminModule adminModule) {
    AdminModuleResource adminModuleResource = new AdminModuleResource();
    adminModuleResource.fromAdminModule(adminModule);
    adminModuleResource.add(linkTo(AdminModuleController.class).slash(adminModuleResource.getId()).withSelfRel());
    return adminModuleResource;
}

public AdminResource toResource(Admin admin) {
    AdminResource adminResource = createResourceWithId(admin.getId(), admin);
    adminResource.fromAdmin(admin);
    adminResource.add(linkTo(AdminController.class).slash(admin.getId()).slash(UriMappingConstants.MODULES).withRel(UriMappingConstants.MODULES));
    return adminResource;
}

Any idea how I can add the links to the parent admin resource even when inside the child admin module resource ?

EDIT: Here is how I build the resources:

public void fromAdminModule(AdminModule adminModule) {
    this.setResourceId(adminModule.getId());
    this.setModule(adminModule.getModule());
    AdminResource adminResource = new AdminResource();
    adminResource.fromAdmin(adminModule.getAdmin());
    this.adminResource = adminResource;
}

public void fromAdmin(Admin admin) {
    this.setResourceId(admin.getId());
    this.setFirstname(admin.getFirstname());
    this.setLastname(admin.getLastname());
    this.setEmail(admin.getEmail().toString());
    this.setPassword(admin.getPassword());
}

Thanks !

Stephane

Signor answered 1/9, 2014 at 9:9 Comment(3)
how are you constructing the AdminModule ?Graiggrail
@ChrisDaMour I added the builders as an edit in the question.Signor
I have read your blog tutorial about this, consider create a JIRA issue asking an improvement about your requirement.Quinque
N
0

Just stumbled on this question, even though it is quite old, but may be worth answering for others implementing similar functionality. Basically, you create embedded resources for AdminModuleResource on your AdminResource and build the links for these embedded resources within your AdminResourceAssembler. The code below is a simplified version of what is posted on this answer

On AdminResource add:

@JsonUnwrapped
private Resources<EmbeddedWrapper> embeddeds;
// + setters/getters

On AdminResourceAssembler add:

EmbeddedWrappers wrapper = new EmbeddedWrappers(true);

List<EmbeddedWrapper> wrappers = (List<EmbeddedWrapper>) super.buildEmbeddables(entity);
Set<AdminModuleResource> moduleResources = adminResource.getModuleResources( );
if(!moduleResources.isEmpty( ))
    wrappers.add(wrapper.wrap(adminModuleResourceAssembler.toResources(moduleResources)));

adminResource.setEmbeddeds(new Resources<>(wrappers));
Nathannathanael answered 18/2, 2016 at 20:15 Comment(1)
I now understand that the HATEOAS is not cascading by default. And that it requires touching the parent resource type to accommodate for the collection of children links. I'm not to excited about touching the resource type for that purpose. I shall skip adding the children links in the parent resource then.Signor

© 2022 - 2024 — McMap. All rights reserved.