question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

HAL-FORMS: problems with the inlining mecanism

See original GitHub issue

The HAL-FORMS specification do not use the inlining mecanism, and rather recommends separating HAL and HAL FORMS documents. If I understood the implementation by Spring HATEOAS in this example, I think it reduces the features that can be offered by an API.

Let’s consider an example with a resource “issue” (/issues/{id}). When performing a GET, I want to see its details + some hypermedia controls to tell me how to “update the details”, how to “assign” it, how to “cancel” it and how to “mark it resolved”. And I want all this actions to be performed in a “command style” resources and not as direct updates of the “issue” resource.

The actual implemented iniling do not allow this design… because there is no way to reference an URI from the _template, it’s all implicitly linked to the self relation.

If the template object was inlined into a link object, then it would be possible to do that.

{
    "_links": {
        "self": {
            "href": "/issues/1",
            "_templates": {
                 "default": {
                      "title":  "update",
                      "method" : "PUT"
                      
                 }
            }
        },
        "assignCommand" : {
            "href" :  "/issues/1/assign-commands",
            "_templates": {
                "default" : {
                      "title":  "assign",
                      "method" : "POST",
                      "other" :" Attributes"
                 }
            }
        },
        "resolveCommand" : {
            "href" :  "/issues/1/resolve-commands",
            "_templates": {
                "default" : {
                      "title":  "resolve",
                      "method" : "POST",
                      "other" :" Attributes"
                 }
            }
        },
        "cancelCommand" : {
            "href" :  "/issues/1/cancel-commands",
            "_templates": {
                "default" : {
                      "title":  "cancel",
                      "method" : "POST",
                      "other" :" Attributes"
                 }
            }
        }
    }
}

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:1
  • Comments:12 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
gregturncommented, Apr 30, 2020

Inside HalFormsTemplateBuilder, if I replace…

List<Affordance> affordances = resource.getLink(IanaLinkRelations.SELF) //
        .map(Link::getAffordances) //
        .orElse(Collections.emptyList());

…with…

List<Affordance> affordances = resource.getLinks().stream()
    .flatMap(link -> link.getAffordances().stream())
    .collect(Collectors.toList());

…then this…

RepresentationModel<?> model = new RepresentationModel<>();

Link selfLink = Affordances.of(Link.of("/issues/1")) //
        .afford(HttpMethod.PUT) //
        .withName("update") //
        .toLink();

Link assignCommand = Affordances.of(Link.of("/issue/1/assign-commands", LinkRelation.of("assignCommand")))
    .afford(HttpMethod.POST) //
    .withName("assignCommand") //
    .toLink();

Link resolveCommand = Affordances.of(Link.of("/issue/1/resolve-commands", LinkRelation.of("resolveCommand")))
    .afford(HttpMethod.POST) //
    .withName("resolveCommand") //
    .toLink();

Link cancelCommand = Affordances.of(Link.of("/issue/1/cancel-commands", LinkRelation.of("cancelCommand")))
    .afford(HttpMethod.POST) //
    .withName("cancelCommand") //
    .toLink();

model.add(selfLink, assignCommand, resolveCommand, cancelCommand);

System.out.println(this.mapper.writeValueAsString(model));

…will yield this HAL-FORMS document…

{
  "_links" : {
    "self" : {
      "href" : "/issues/1"
    },
    "assignCommand" : {
      "href" : "/issue/1/assign-commands"
    },
    "resolveCommand" : {
      "href" : "/issue/1/resolve-commands"
    },
    "cancelCommand" : {
      "href" : "/issue/1/cancel-commands"
    }
  },
  "_templates" : {
    "default" : {
      "method" : "put",
      "properties" : [ ]
    },
    "cancelCommand" : {
      "method" : "post",
      "properties" : [ ]
    },
    "resolveCommand" : {
      "method" : "post",
      "properties" : [ ]
    },
    "assignCommand" : {
      "method" : "post",
      "properties" : [ ]
    }
  }
}
1reaction
samihuscommented, Jan 24, 2020

According to the HAL FORMS spec, _templates is a top-level property.

True, but in a HAL FORMS Document. If we consider that HAL FORMS document is identified by the relation in the Link object of the HAL document, then inlining it should be under the link object it refers to. Not at a global level…

Read more comments on GitHub >

github_iconTop Results From Across the Web

Spring HATEOAS - Reference Documentation
The core problem it tries to address is link creation and ... HAL Forms now does not render property attributes if their value...
Read more >
RESTful services with HATEOAS. Hypermedia - 2022
In this post, we feature a comprehensive article about RESTful services with HATEOAS. Hypermedia which is the Secret Ingredient of REST. 1.
Read more >
Allow to define HAL FORMS options based on the ... - GitHub
We could allow users to post-process the statically computed options, but that would require us to expose API to inspect the inline and...
Read more >
Inline expansion - Wikipedia
In computing, inline expansion, or inlining, is a manual or compiler optimization that replaces a function call site with the body of the...
Read more >
Kovix KVZ1 6mm Disc Lock - Fluo Orange | Halfords UK
Every year thousands of bicycles, scooters and motorcycles are stolen in the UK and this remains a huge problem. Surprisingly, many owners do...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found