4
votes

Using the HATEOAS links functionality which is great I am trying to output a templated url to highlight the filter params available to a user

Example controller method

@RequestMapping(value = "/persons", method = RequestMethod.GET, produces = "application/hal+json")
public PersonsResource getPersons (@RequestParam(required = false, value = "name") String name, @RequestParam(required = false, value = "age") Integer age) {
...
    personsResource.add(ControllerLinkBuilder.linkTo(ControllerLinkBuilder.methodOn(PersonController.class).getPersons(name, age)).withSelfRel());
}

When this method is invoked with no parameters links appears

_links: {
    self: {
        href: "http://myserver:8080/persons"
    }
}

But I'd like

href: "http://myserver:8080/persons?name={name}&age={age}

Even better if one param was supplied then

href: "http://myserver:8080/persons?name={name}&age=21

Icing on the cake would be query parameters of {...] to be ignored ?

Does anyone know if this is possible using the Spring HATEOAS api ? I have managed to code around this but it seems like a reasonable suggestion for the API ?

3

3 Answers

4
votes

You could try AffordanceBuilder from spring-hateoas-ext as a drop-in replacement for ControllerLinkBuilder. It creates template variables for parameters you leave undefined in the linkTo-methodOn idiom.

It not only allows to create templates, but also gives you the full capabilities of a RFC 5988 Link and has knowledge about request bodies, so that one can render Hydra or Html or Siren Responses with form-style request descriptors from it.

Disclaimer: I'm the author of spring-hateoas-ext.

0
votes

I guess, the framework is still pretty immature.

I have v.0.11.0.RELEASE and have the same issue.

When you don't supply parameter values you don't have template URL as a result of the ControllerLinkBuilder.linkTo(methodOn) invocation. It's just the way you said, base path from the method annotation.

But when you supply parameter values it's exactly like you say: https://stackoverflow.com/some/service/path?name=SomeName&age=11 (in my case parameters are different, but the effect is the one you see here)

The 'conceptually correct' URL should be

https://stackoverflow.com/some/service/path{?name,age}

But Spring HATEOAS doesn't support this. Unless you want to append it yourself in the code. Which is really undesirable.

I checked the UriBuilder from JavaEE, it works the same way, no templating for query parameters supported.

0
votes

This has been addressed in the latest spring-hateoas version. You can check the following issue:
https://github.com/spring-projects/spring-hateoas/issues/169

You should be able to get the required templated URL using something like:

resource.add(linkTo(methodOn(Controller.class).method(null)).withSelfRel());