Skip to main content

Declarative Hyperlinking Enhancements

Posted by mhadley on March 17, 2010 at 12:15 PM PDT

I've spent some time fleshing out the code in the experimental declarative hyperlinking module I blogged about earlier. In that earlier entry I showed how you could use the new @Link annotation with existing URI templates either explicitly like this:

@Link("widgets/{id}")
URI link;

or by referencing a resource class @Path annotation value like this:

@Link(resource=WidgetResource.class)
URI link;

Expression Language Support

With the latest trunk code you can now use EL in explicit @Link templates, thanks to Ed Burns for helping to get me bootstrapped with the EL APIs. E.g.:

@Link("widgets/${instance.id}")
URI link;

The above would extract the value of the id property of the instance bean. Three beans are currently supported:

instance
The object whose class contains the @Link annotation currently being processed.
entity
The response entity object returned by the resource class method.
resource
The resource class instance that returned the entity.

Its straightforward to add others but these seemed like a useful set to start with.

Custom Bindings

By default, a URI template parameter is replaced by the value of a same-named property in the current instance. The following two annotations are therefore equivalent:

@Link("{id}")
@Link("${instance.id}")

Custom bindings allow the source of the value of a URI template parameter to be changed, e.g.:

@Link(value="{id}", bindings={
  @Binding(name="id", value="${resource.widgetId}")
})

In the above the {id} template parameter will be replaced with the value of the widgetId property of the resource class instance that returned the response. The name property of an @Binding gives the name of a URI template parameter, the value is an EL expression that defines how to get the value of the parameter.

Comments

one scenario i've run into

one scenario i've run into that i'd like to see addressed - being able to return different uris depending on the request context - for example, if a method returns a list of users, the uri inserted for each user may depend on whether the intention is to associate the user w resource A or B (which would depend on the request context, maybe the referrer path)

That should be possible already

That scenario should be possible given that you can call into any getter method on the representation or resource instances. E.g. the resource class could have a method like getContextualUserUri that returns an appropriate computed URI and you could then use @Link("${resource.contextualUserUri}") in the respresentation.