https://github.com/openapi-tools/jackson-dataformat-hal
Dataformat extension for Jackson to handle HAL JSON
https://github.com/openapi-tools/jackson-dataformat-hal
hal hal-extension hal-json hal-maven-module hateoas jackson
Last synced: about 2 months ago
JSON representation
Dataformat extension for Jackson to handle HAL JSON
- Host: GitHub
- URL: https://github.com/openapi-tools/jackson-dataformat-hal
- Owner: openapi-tools
- License: mit
- Created: 2017-09-07T07:41:03.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2024-07-27T11:28:50.000Z (about 1 year ago)
- Last Synced: 2024-12-09T12:50:21.399Z (10 months ago)
- Topics: hal, hal-extension, hal-json, hal-maven-module, hateoas, jackson
- Language: Java
- Homepage:
- Size: 110 KB
- Stars: 24
- Watchers: 6
- Forks: 6
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Overview
This project contains a [Jackson](https://github.com/FasterXML/jackson) extension component to support the
[HAL JSON](https://tools.ietf.org/html/draft-kelly-json-hal-08) format both with respect to
serializing and deserializing.The goal is to handle HAL links and embedded objects as POJO properties with a data-binding similar to
the normal Jackson JSON handling.# Status
Module is considered production ready.[](https://maven-badges.herokuapp.com/maven-central/io.openapitools.jackson.dataformat/jackson-dataformat-hal/)
[](https://www.javadoc.io/doc/io.openapitools.jackson.dataformat/jackson-dataformat-hal)
[](https://travis-ci.org/openapi-tools/jackson-dataformat-hal)
[](https://codecov.io/gh/openapi-tools/jackson-dataformat-hal)
[](https://snyk.io/test/github/openapi-tools/jackson-dataformat-hal)# Usage
The extension comes with a few annotations to mark the HAL links and embedded objects as well as a class
to handle the HAL link specification. A POJO used for HAL formatted JSON could look as follows.```java
@Resource
class Model {
String modelProperty;@Link
HALLink self;@Link("rel:associated")
HALLink relation;@EmbeddedResource
AssociatedModel associated;
}@Resource
class AssociatedModel {
String associatedProperty;@Link
HALLink self;
}
```The `@Resource` annotation marks the POJO as a HAL based resource. The `@Link` and `@Embedded` annotations
marks links to go into the `_links` object and embedded resources to go into the `_embedded` object respectively.
HAL links must be defined using the `HALLink` class as this models the properties defined in the HAL specification.
Both `@Link` and `@Embedded` fields may be collections or arrays.The JSON resulting from the above small POJO model would look like the following.
```json
{
"_links": {
"self": { "href": "https://..."},
"rel:associated": { "href": "https://..."}
},
"_embedded": {
"associated": {
"_links": {
"self": { "href": "https://..." }
},
"associatedProperty": "..."
}
},
"modelProperty": "..."
}
```All fields which are not annotated will be handled by the normal Jackson JSON data-binding.
## Including Curies
```java
@Resource
@Curie(curie = "curie", href = "http://example.com/doc/{rel}")
class Model {
String modelProperty;@Link
HALLink self;@Link("rel:associated")
HALLink relation;@Link(value = "curieLink", curie = "curie")
HALLink curieLink;}
``````java
@Resource
@Curies({
@Curie(href = "http://docs.my.site/{rel}", curie = "curie1"),
@Curie(href = "http://docs.other.site/{rel}", curie = "curie2")})class Model {
String modelProperty;@Link
HALLink self;@Link("rel:associated")
HALLink relation;@Link(value = "curieLink11", curie = "curie1")
HALLink curieLink11;@Link(value = "curieLink21", curie = "curie2")
HALLink curieLink21;@Link(value = "curieLink22", curie = "curie2")
HALLink curieLink22;@Link(value = "curieLink23", curie = "curie2")
HALLink curieLink23;}
```
The resulting JSON would be:```json
{
"_links": {
"curies": [{
"name": "curie1",
"href": "http://docs.my.site/{rel}",
"templated": "true"
},{
"name": "curie2",
"href": "http://docs.other.site/{rel}",
"templated": "true"
}],
"self": { "href": "https://..."},
"rel:associated": { "href": "https://..."},
"curie1:link11": { "href": "https://...", "templated" : "..."},
"curie2:link21": { "href": "https://...", "templated" : "..."},
"curie2:link22": { "href": "https://...", "templated" : "..."}
},
"_embedded": {
"associated": {
"_links": {
"self": { "href": "https://..." }
},
"associatedProperty": "..."
}
},
"modelProperty": "..."
}
```The above is equivalent to:
```json
{
"_links": {
"self": { "href": "https://..."},
"rel:associated": { "href": "https://..."},
"http://docs.my.site/link11": { "href": "https://...", "templated" : "..."},
"http://docs.other.site/link21": { "href": "https://...", "templated" : "..."},
"http://docs.other.site/link22": { "href": "https://...", "templated" : "..."}
},
"_embedded": {
"associated": {
"_links": {
"self": { "href": "https://..." }
},
"associatedProperty": "..."
}
},
"modelProperty": "..."
}
```Both will be supported for deserialization. Also if curie prefixes in the incoming document
is chosen to be different from the prefixes in the POJO annotations deserialization will be
supported.## Serializing POJOs as HAL JSON
Serialization is similar to the normal JSON serialization using the `HALMapper` instead of the
`ObjectMapper`.```java
ObjectMapper halMapper = new HALMapper();
String json = halMapper.writeValueAsString(new POJO());
```## Deserializing POJOs from XML
Deserialization is also similar to the normal JSON handling using the `HALMapper`.
```java
ObjectMapper halMapper = new HALMapper();
POJO value = halMapper.readValue("{..json..}", POJO.class);
```## Using HAL Extension in JAX-RS Application
To use the HAL extension in a JAX-RS application you can add the [jackson-jaxrs-providers](https://github.com/FasterXML/jackson-jaxrs-providers) module
to your application and use this to ensure the `HALMapper` is being used.```java
@ApplicationPath("/")
public class MyApplication extends Application {
private final Set singletons = new HashSet<>();public MyApplication() {
singletons.add(new JacksonJsonProvider(new HALMapper()));
}@Override
public Set getSingletons() {
return Collections.unmodifiableSet(singletons);
}
}
```## Using HAL Extension in JAX-RS Client
Using the HAL extension in a JAX-RS client works very similar to using it in an application. The
jackson-jaxrs-providers can be used to register the `HALMapper`.```java
ClientBuilder cb = ClientBuilder.newBuilder();
Client client = cb.register(new JacksonJsonProvider(new HALMapper())).build();
```
## HALLink extended with temporal aspect
The HALLink is extended with a `seen` property. This is beyond the current specification of HAL.
An addendum or change to HAL will be proposed to incoorporate the seen property in the `_Link` specification.
The purpose of the `seen` property is to give consumers of a service the ability to judge for themselves whether
the last time a HAL related object was seen either as a `link` or as an `embedded` object.## Knows Limitations
The Wildfly application server comes with both a Jackson and Jackson 2 module which takes precedence
over the ones registered with the JAX-RS client. Thus to make sure the HAL extension is actually
used when creating a JAX-RS client running inside Wildfly you need to exclude the Jackson modules in
the `jboss-deployment-structure.xml` file.```xml
```