/hate

HATEOAS with HAL for Java

Primary LanguageJavaMIT LicenseMIT

hate

HATEOAS with HAL for Java. Create hypermedia APIs by easily serializing your Java models into HAL JSON.
More info in the wiki.

Gitter
Build Status
Codacy Badge
Codecov
Javadocs
Maven Central


Install with Maven

<dependencies>
  <dependency>
    <groupId>black.door</groupId>
    <artifactId>hate</artifactId>
    <version>v1r4t5</version>
  </dependency>
</dependencies>

Basic usage

Implement the HalResource interface in your model by implementing the location() and representationBuilder() methods. For example:

public class Order implements HalResource{

	private int id;
	private double total;
	private String currency;
	private String status;
	//note: Basket and Customer implement HalResource
	private Basket basket;
	private Customer customer;

	...

	@Override
	public URI location(){
		return new URI("/orders/" + id);
	}
	
	@Override
	public HalRepresentationBuilder representationBuilder() {
		return HalRepresentation.builder()
				.addProperty("total", total)
				.addProperty("currency", currency)
				.addProperty("status", status)
				.addLink("basket", basket)
				.addLink("customer", customer)
				.addLink("self", this);
	}
}	

Now to get the HalRepresentation of an Order object, simply do HalRepresentation hal = myOrder.asEmbedded(). You can serialize hal using hal.serialize() or with Jackson (eg. new ObjectMapper().writeValueAsString(hal))

The result would look like this:

{
  "total": 30,
  "currency": "USD",
  "status": "shipped",
  "_links": {
    "basket": {
      "href": "/baskets/97212"
    },
    "self": {
      "href": "/orders/123"
    },
    "customer": {
      "href": "/customers/7809"
    }
  }
}

Paginated Collections

To get a paginated HAL representation of a REST collection, simply use HalRepresentation.paginated(String, String, Stream, long, long).
For example:

Collection<Order> orders;

HalRepresentation hal = HalRepresentation.paginated(
	"orders", // the name of the resource collection
	"/orders", // the path the resource collection can be found at
	orders.stream(), // the resources
	pageNumber,
	pageSize // the number of resources per page
	).build();

Would give you something like this:

{
  "_links": {
    "next": {
      "href": "/orders?page=2"
    },
    "self": {
      "href": "/orders"
    }
  },
  "_embedded": {
    "orders": [
      {
        "total": 30,
        "currency": "USD",
        "status": "shipped",
        "_links": {
          "basket": {
            "href": "/baskets/97212"
          },
          "self": {
            "href": "/orders/123"
          },
          "customer": {
            "href": "/customers/7809"
          }
        }
      },
      {
        "total": 20,
        "currency": "USD",
        "status": "processing",
        "_links": {
          "basket": {
            "href": "/baskets/97213"
          },
          "self": {
            "href": "/orders/124"
          },
          "customer": {
            "href": "/customers/12369"
          }
        }
      }
    ]
  }
}