Skip to content
Nathaniel Fischer edited this page Mar 19, 2016 · 6 revisions

The hate library is made up of a few core components, HalResources, HalLinks, and HalRepresentations.

HalResource

All of your model objects will implement HalResource. By implementing the methods in this interface, users of your class will be able to serialize, embed, or link your model in HAL format.

HalRepresentation

The HalRepresentation and HalRepresentationBuilder classes are the meat of the hate library. Like in the HAL spec, a HalRepresentation is made up of properties, embedded resources and linked resources. HalRepresentations are created using the HalRepresentationBuilder. Obtain a builder with HalRepresentation.builder(), easy.

Properties

Properties are simple, they are the attributes that describe a resource. In fact, a HAL representation with only properties and no linked or embedded resources looks exactly the same as a serialized resource in a non-hypermedia API. Building such a representation for a person using hate might look like this:

builder
	.addProperty("name", "jim")
	.addProperty("age", 25)
	.addProperty("sex", "male")
	.build();

Serialized, it would look like this:

{
  "name": "jim",
  "age": 25,
  "sex": "male"
}
Embedded resources

Embed a resource in a representation like this:

builder.addEmbedded("res", myResource);

Embedded resources can be used for a variety of reasons. One reason might be that a related resource is very important to a given resource, and it doesn't make sense to present the given resource without the entire content of the related resource. Another reason might be to increase performance and save bandwidth, see "Expanding links into embeds" for more info on how this can be done efficiently.
One important thing to note about embedded resources, is that they are recursive. Each embed is an entire HAL representation of a resource, complete with its own links and embeds.
This means that

  • embedding many resources with many of their own resources can increase the size of your serialized object quickly
  • circular embeds will cause a stack overflow
Linked resources

Adding a linked resource is just like adding an embedded resource, just use

builder.addLink("res", myLink)

While resources you want to embed must be sub-classes of HalResource, links can be a HalResource, a HalLink or a URL(the url method is just a convenience method for creating a HalLink). Read more about HAL links in the section on HalLinks.

Expanding links into embeds

Sometimes you will want to change a linked resource into an embedded resource for an object which has already been configured. This can easily be done using a HalResource with myResource.asEmbedded("names", "of", "links") or with a HalRepresentationBuilder using myBuilder.expand("resourceName").

Default implementation of representationBuilder

See the relevant wiki page.

Collections of linked and embedded resources

Links or embeds can be collections as well as a singe resource. Adding a collection straight up is just the same as a single resource.

Collection<MyResourceImpl> resources = new LinkedList<>();

builder.addLink("otherThings", resources);
//or
builder.addEmbedded("otherThings", resources);

However the builder also has some functionality for handing name collisions. Adding two single resources of the same type (link or embed) will cause them to be put together into a collection. Adding a collection of resources when there already exists a single resource of the same type with the same name will cause that resource to be added to the collection. Adding a single resource when there already exists a collection of resources of the same type with the same name will cause that resource to be added to the collection.

HalLink

In HAL a link is used to express when a given resource has a relationship with another resource, but the related resource is either too large or not important enough to be embedded with the given resource. Instead of embedding the related resource, a link tells where and (optionally) how to access the related resource.

Creating a link for a resource you don't have

If you have a resource, for example a model that implements HalResource, creating a link is easy; you just call myResource.asLink(). However sometimes you will have a resource but it will be related to a resource you don't have, such as one that might be in a different micro-service. You don't need to retrieve the entire resource, all you need is enough to know where it is. You can easily use the link builder like this:

URI uri = new URI("http://service2.mysite.com/resources/5");
HalLink link = HalLink.builder()
    .name("the other resource")
    .href(uri)
    .build();

URI templates for queryable resources

HAL links don't always have to link to a specific URI, they can also be a template that tells how to build a URI. hate uses the handy URI template library for URI templating. Once you understand URI templates, making a link with a template is just like making one with a concrete URI.

UriTemplate template = UriTemplate.buildFromTemplate("http://example.com")
    .literal("/foo")
    .path(var("thing1"),var("explodedThing", true))
    .fragment(var("prefix", 2))
    .build();
HalLink link = HalLink.builder()
    .name("the other resource")
    .href(template)
    .build();