# Declarative Hyperlinking

RESTful APIs must be hypertext-driven. JAX-RS currently offers &jaxrs.core.UriBuilder; to simplify URI creation but Jersey adds an additional annotation-based alternative that is described here.

## Links in Representations

Links are added to representations using the `@Ref` annotation on entity class fields. The Jersey runtime is responsible for injecting the appropriate URI into the field prior to serialization by a message body writer. E.g. consider the following resource and entity classes:

    @Path("widgets")
    public class WidgetsResource {
      @GET
      public Widgets get() {
        return new Widgets();
      }
    }

    public class Widgets {
      @Ref(resource=WidgetsResource.class)
      URI u;
    }

After a call to `WidgetsResource#get`, the Jersey runtime will inject the value "/context/widgets"

Where `/context` is the application deployment context.

into the returned `Widgets` instance. If an absolute URI is desired instead of an absolute path then the annotation can be changed to `@Ref(resource=WidgetsResource.class, style=ABSOLUTE)`.

The above usage works nicely when there's already a URI template on a class that you want to reuse. If there's no such template available then you can use a literal value instead of a reference. E.g. the following is equivalent to the earlier example: `@Ref(value="widgets", style=ABSOLUTE)`.

## Binding Template Parameters

Referenced or literal templates may contain parameters. Two forms of parameters are supported:

- URI template parameters, e.g. `widgets/{id}` where `{id}` represents a variable part of the URI.

- EL expressions, e.g. `widgets/${instance.id}` where `${instance.id}` is an EL expression.

Parameter values can be extracted from three implicit beans:

`instance`

  Represents the instance of the class that contains the annotated field.

`entity`

  Represents the entity class instance returned by the resource method.

`resource`

  Represents the resource class instance that returned the entity.

By default URI template parameter values are extracted from the implicit `instance` bean, i.e. the following two annotations are equivalent:

    @Ref("widgets/{id}")
    @Ref("widgets/${instance.id}")

The source for URI template parameter values can be changed using the `@Binding` annotation, E.g. the following two annotations are equivalent:

    @Ref(value="widgets/{id}", bindings={
      @Binding(name="id" value="${resource.id}"}
    )
    @Ref("widgets/${resource.id}")

## Conditional Link Injection

Link value injection can be made conditional by use of the `condition` property. The value of this property is a boolean EL expression and a link will only be injected if the condition expression evaluates to true. E.g.:

    @Ref(value="widgets/${instance.id}/offers",
      condition="${instance.offers}")
    URI offers;

In the above, a URI will only be injected into the `offers` field if the `offers` property of the instance is `true`.

## Link Headers

HTTP Link headers can also be added to responses using annotations. Instead of annotating the fields of an entity class with `@Ref`, you instead annotate the entity class itself with `@Link`. E.g.:

    @Link(
      value=@Ref("widgets/${resource.nextId}"),
      rel="next"
    )

The above would insert a HTTP Link header into any response whose entity was thus annotated. The `@Link` annotation contains properties that map to the parameters of the HTTP Link header. The above specifies the link relation as `next`. All properties of the `@Ref` annotation may be used as described above.

Multiple link headers can be added by use of the `@Links` annotation which can contain multiple `@Link` annotations.

## Configuration

Declarative hyperlinking support is provided in the form of a filter. First, the application must declare a dependency on the `jersey-server-linking` module:

    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-server-linking</artifactId>
      <version>${jersey-version}</version>
    </dependency>

Second the filter needs to be installed in the application either programmatically by adding:

    com.sun.jersey.server.linking.LinkFilter

to the list defined by:

    com.sun.jersey.spi.container.ContainerResponseFilters

or using a `web.xml` init parameter:

    <init-param>
      <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
      <param-value>com.sun.jersey.server.linking.LinkFilter</param-value>
    </init-param>

See the jersey-server-linking-sample for more details.