Links and embedded resources are keyed by a relation name. Link relations are descriptive attributes that define the type of link, or the relationship between the source and destination resources, for example a self
link. If a standard relation name is not appropriate, a URI is used for the relation name. The relations registry allows for Compact URI (CURIE) support where a prefix can be configured to reference a URI. The relation name then becomes a concatenation of this prefix with a shortened name. By default, the CURIE prefix is configured in the registry as oc=/rels{rel}
and is used if no other prefix is explicitly provided when a relation name is specified. For example, oc:checkout
would resolve the relation name /rels/checkout
. Standardized link relations are a foundation of HATEOAS, as they allow the user to understand the meaning of the available state transitions in a REST system.
A global standard set of link relations can be found at www.iana.org/assignments/link-relations/link-relations.xml. For additional information on link relations, refer to the Using Links with HATEOAS section.
Link relations, though defined in multiple endpoints of a resource, are aggregated at the resource level. When an endpoint method is invoked, the response includes the links of other endpoints of that resource. The following is an example of a resource where a linkRelation
attribute is specified for the endpoints SubmitOrder
and getOrder
:
The request is made for getOrder endpoint. @Path("/orders") public class OrderRestResource { @POST @Path(/{orderId}/submitOrder) @Endpoint(id="/orders/{orderId}/submitOrder#POST", linkRelation="submitOrder") public Object submitOrder(@PathParam("orderId") pOrderId, JSONObject pOrderJSON) { } @GET @Path(/{orderId}) @Endpoint(id="/orders/{orderId}#GET", linkRelation="getOrder") public Object getOrder(@PathParam("orderId") pOrderId) { } } Request http://localhost:9080/public/v1/orders/o12345 Method: GET Response: { links :[ {"rel ": "self", "href": "/orders/o12345"}, {"rel ": "submitOrder", "href": "/orders/o12345/submitOrder"} ] }
Note that any link relation names that are not in the default set should define themselves using a URI and should be described as part of your documentation. Use the RelationsRegistry
component, which holds the definitions for the link relations, to define any new link relations:
$class=atg.service.jaxrs.RelationsRegistry $classloader=/atg/dynamo/service/jaxrs/JerseyClassLoaderService relationDefinitions=\ oc=/rels/{rel}
For example, if you use a non-standard link, such as SubmitOrder
, you can use the relationDefinitions
property of the RelationsRegistry
component to add the new definition. The following example shows how the oc
relation definition is added to the RelationsRegistry
:
relationDefinitions=\ oc=/rels/{rel}
When building the RepresentationModel
, prefix the relation name with the relation definition key oc
. The link will be expanded by the message body writer. For example:
RepresentationModel model = new RepresentationModel.Builder().state(order). links(Link.fromPath("/order/o12345").rel("oc:submitOrder"));
The message body writers parse relation names and expand the definition while writing the JSON response for an Oracle JSON media type, so the output would be:
{ links :[ { "rel" : "public/v1/rels/submitOrder", "href": "/orders/012345" }]}
When using a HAL response, the link is left in compact form, with a separate section output in the response.
Customizing Self Links
If an endpoint needs a custom self link, use the selfLinkFromContext
method. This generates a self
link based on the context. If a collection resource endpoint needs to respond with a singular resource representation, then the endpoint must invoke the overloaded version of the method selfLinkFromContext(true,
singular ID
)
to generate the self link for the singular resource.
Note: If you use a link that is not standard, you must have a URI pointing to the self
link.