Spring-hateoas: Affordance for rels other than self are not rendering.

Created on 19 Sep 2019  路  12Comments  路  Source: spring-projects/spring-hateoas

resource.add(
    linkTo(methodOn(UserRestApi.class).getAll(pr.getPage(), pr.getSize())).withSelfRel()
        .andAffordance(afford(methodOn(UserRestApi.class).create(null, null))));

Renders the _templates as expected.

resource.add(
    linkTo(methodOn(UserRestApi.class).create(null, null)).withRel(CREATE)
        .andAffordance(afford(methodOn(UserRestApi.class).create(null, null))));

or

resource.add(Affordances.of(
        linkTo(methodOn(UserRestApi.class).create(null, null)).withRel(CREATE))
        .afford(HttpMethod.POST)
        .withInput(CreateUserCmd.class)
        .withName("create_user")
        .toLink());

Does not render any _templates section.

enhancement documentation mediatypes

Most helpful comment

One "use case" to work with other links is practicality @odrotbohm. for instance, we have an API like

GET /events/{id}

{
  _links: {
     ...
     incidents: {
        href: /events/{id}/incident
     }
  }
}

for consumer it is more practical to already know at this point what it is possible on the list of incidents without having to retrieve the list. It just saves a call, so not a big deal imo, but one of those small things that might help adoptions.

I can see how enabling affordances on all links might causes other issues, like the need to come up with a convention to link template to link and having _templates being extremely large, so I am not sure the "use case" actually makes sense

All 12 comments

If you鈥檙e talking about HAL-FORMS, it鈥檚 probably due to the guard class at the top of this => https://github.com/spring-projects/spring-hateoas/blob/master/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplateBuilder.java

Does your model have no self link at all?

Yes, this is HAL-FORMS.
If I do this, there are no affordances for the create relationship.

resource.add(
    linkTo(methodOn(UserRestApi.class).getAll(pr.getPage(), pr.getSize())).withSelfRel());

resource.add(Affordances.of(
        linkTo(methodOn(UserRestApi.class).create(null, null)).withRel(CREATE))
        .afford(HttpMethod.POST)
        .withInput(CreateUserCmd.class)
        .withName("create_user")
        .toLink());

Looks like we're running into some "spec + implementation" question here. The spec initially states:

The _links element contains any links associated with the HAL-FORMS document. For this release, the only valid link object is the self link object.

I assume that this is the reason the guard exists that Greg pointed to, as the subsequent code tries to look up the affordances associated with the self link. So up to this point I'd argue were in line with the specification.

I'd still like to learn what the actual use case is for starting with a non-self link in the first place.

It's my misunderstanding of the Spec. My assumption was that the data and template was in the same request. After reading this section of the spec, I realize that the forms data is in a second request (more like ALPS and the profile link). I think the documentation should be updated to reflect this.

One "use case" to work with other links is practicality @odrotbohm. for instance, we have an API like

GET /events/{id}

{
  _links: {
     ...
     incidents: {
        href: /events/{id}/incident
     }
  }
}

for consumer it is more practical to already know at this point what it is possible on the list of incidents without having to retrieve the list. It just saves a call, so not a big deal imo, but one of those small things that might help adoptions.

I can see how enabling affordances on all links might causes other issues, like the need to come up with a convention to link template to link and having _templates being extremely large, so I am not sure the "use case" actually makes sense

We are also looking for a solution for this usecase.
How can I help? I can create a pull request if needed.

Sorry, I should have started with what follows.

Looks like we're running into some "spec + implementation" question here. The spec initially states:

The _links element contains any links associated with the HAL-FORMS document. For this release, the only valid link object is the self link object.

Since https://github.com/mamund/hal-forms/issues/58, it seems that the link can have any value now.
Therefore, shouldn't the guard be removed?

I think we can make use of target attribute here.
If the affordance was to be built on a non-self relation, the template would hold a target attribute pointing to the relation link.

If I look at HalFormsTemplateBuilder it looks like this should already work. We already process all links added to the resource and transparently add the target attribute if either no self link is present or the target URI is different than the one for the self link. It seems this was introduced in the context of #1427. Would you mind re-checking?

Oh that would be great!
I'll come back to you once we have upgraded to the latest version.

Tested on 1.3.1. It works as expected :tada:

Lovely. Happy coding!

Was this page helpful?
0 / 5 - 0 ratings