{"id":21684685,"url":"https://github.com/openapi-tools/jackson-dataformat-hal","last_synced_at":"2025-08-20T12:31:29.777Z","repository":{"id":29620463,"uuid":"102706889","full_name":"openapi-tools/jackson-dataformat-hal","owner":"openapi-tools","description":"Dataformat extension for Jackson to handle HAL JSON","archived":false,"fork":false,"pushed_at":"2024-07-27T11:28:50.000Z","size":113,"stargazers_count":24,"open_issues_count":5,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-12-09T12:50:21.399Z","etag":null,"topics":["hal","hal-extension","hal-json","hal-maven-module","hateoas","jackson"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"anonyome/jackson-dataformat-hal","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openapi-tools.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-07T07:41:03.000Z","updated_at":"2024-07-13T19:07:41.000Z","dependencies_parsed_at":"2022-07-22T08:32:17.161Z","dependency_job_id":null,"html_url":"https://github.com/openapi-tools/jackson-dataformat-hal","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openapi-tools%2Fjackson-dataformat-hal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openapi-tools%2Fjackson-dataformat-hal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openapi-tools%2Fjackson-dataformat-hal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openapi-tools%2Fjackson-dataformat-hal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openapi-tools","download_url":"https://codeload.github.com/openapi-tools/jackson-dataformat-hal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230423563,"owners_count":18223435,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hal","hal-extension","hal-json","hal-maven-module","hateoas","jackson"],"created_at":"2024-11-25T16:16:46.615Z","updated_at":"2024-12-19T11:12:11.840Z","avatar_url":"https://github.com/openapi-tools.png","language":"Java","readme":"# Overview\n\nThis project contains a [Jackson](https://github.com/FasterXML/jackson) extension component to support the\n[HAL JSON](https://tools.ietf.org/html/draft-kelly-json-hal-08) format both with respect to\nserializing and deserializing.\n\nThe goal is to handle HAL links and embedded objects as POJO properties with a data-binding similar to\nthe normal Jackson JSON handling.\n\n# Status\nModule is considered production ready.\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.openapitools.jackson.dataformat/jackson-dataformat-hal/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.openapitools.jackson.dataformat/jackson-dataformat-hal/)\n[![Javadoc](http://javadoc.io/badge/io.openapitools.jackson.dataformat/jackson-dataformat-hal.svg)](https://www.javadoc.io/doc/io.openapitools.jackson.dataformat/jackson-dataformat-hal)\n[![Build status](https://travis-ci.org/openapi-tools/jackson-dataformat-hal.svg?branch=master)](https://travis-ci.org/openapi-tools/jackson-dataformat-hal)\n[![Coverage Status](https://codecov.io/gh/openapi-tools/jackson-dataformat-hal/coverage.svg?branch=master)](https://codecov.io/gh/openapi-tools/jackson-dataformat-hal)\n[![Known Vulnerabilities](https://snyk.io/test/github/openapi-tools/jackson-dataformat-hal/badge.svg)](https://snyk.io/test/github/openapi-tools/jackson-dataformat-hal) \n\n\n# Usage\n\nThe extension comes with a few annotations to mark the HAL links and embedded objects as well as a class\nto handle the HAL link specification. A POJO used for HAL formatted JSON could look as follows.\n\n```java\n@Resource\nclass Model {\n    String modelProperty;\n\n    @Link\n    HALLink self;\n\n    @Link(\"rel:associated\")\n    HALLink relation;\n\n    @EmbeddedResource\n    AssociatedModel associated;\n}\n\n@Resource\nclass AssociatedModel {\n    String associatedProperty;\n\n    @Link\n    HALLink self;\n}\n```\n\nThe `@Resource` annotation marks the POJO as a HAL based resource. The `@Link` and `@Embedded` annotations\nmarks links to go into the `_links` object and embedded resources to go into the `_embedded` object respectively.\nHAL links must be defined using the `HALLink` class as this models the properties defined in the HAL specification.\nBoth `@Link` and `@Embedded` fields may be collections or arrays.\n\nThe JSON resulting from the above small POJO model would look like the following.\n\n```json\n{\n    \"_links\": {\n        \"self\": { \"href\": \"https://...\"},\n        \"rel:associated\": { \"href\": \"https://...\"}\n    },\n    \"_embedded\": {\n        \"associated\": {\n            \"_links\": {\n                \"self\": { \"href\": \"https://...\" }\n            },\n            \"associatedProperty\": \"...\"\n        }\n    },\n    \"modelProperty\": \"...\"\n}\n```\n\nAll fields which are not annotated will be handled by the normal Jackson JSON data-binding.\n\n## Including Curies\n\n```java\n@Resource\n@Curie(curie = \"curie\", href = \"http://example.com/doc/{rel}\")\nclass Model {\n    String modelProperty;\n\n    @Link\n    HALLink self;\n\n    @Link(\"rel:associated\")\n    HALLink relation;\n\n    @Link(value = \"curieLink\", curie = \"curie\")\n    HALLink curieLink;\n\n}\n```\n\n```java\n@Resource\n@Curies({\n    @Curie(href = \"http://docs.my.site/{rel}\", curie = \"curie1\"),\n    @Curie(href = \"http://docs.other.site/{rel}\", curie = \"curie2\")})\n\nclass Model {\n    String modelProperty;\n\n    @Link\n    HALLink self;\n\n    @Link(\"rel:associated\")\n    HALLink relation;\n\n    @Link(value = \"curieLink11\", curie = \"curie1\")\n    HALLink curieLink11;\n\n    @Link(value = \"curieLink21\", curie = \"curie2\")\n    HALLink curieLink21;\n\n    @Link(value = \"curieLink22\", curie = \"curie2\")\n    HALLink curieLink22;\n\n    @Link(value = \"curieLink23\", curie = \"curie2\")\n    HALLink curieLink23;\n\n}\n```\nThe resulting JSON would be:\n\n```json\n{\n    \"_links\": {\n        \"curies\": [{\n            \"name\": \"curie1\",\n            \"href\": \"http://docs.my.site/{rel}\",\n            \"templated\": \"true\"\n        },{\n            \"name\": \"curie2\",\n            \"href\": \"http://docs.other.site/{rel}\",\n            \"templated\": \"true\"\n        }],\n        \"self\": { \"href\": \"https://...\"},\n        \"rel:associated\": { \"href\": \"https://...\"},\n        \"curie1:link11\": { \"href\": \"https://...\", \"templated\" : \"...\"},\n        \"curie2:link21\": { \"href\": \"https://...\", \"templated\" : \"...\"},\n        \"curie2:link22\": { \"href\": \"https://...\", \"templated\" : \"...\"}\n    },\n    \"_embedded\": {\n        \"associated\": {\n            \"_links\": {\n                \"self\": { \"href\": \"https://...\" }\n            },\n            \"associatedProperty\": \"...\"\n        }\n    },\n    \"modelProperty\": \"...\"\n}\n```\n\nThe above is equivalent to:\n\n```json\n{\n    \"_links\": {\n        \"self\": { \"href\": \"https://...\"},\n        \"rel:associated\": { \"href\": \"https://...\"},\n        \"http://docs.my.site/link11\": { \"href\": \"https://...\", \"templated\" : \"...\"},\n        \"http://docs.other.site/link21\": { \"href\": \"https://...\", \"templated\" : \"...\"},\n        \"http://docs.other.site/link22\": { \"href\": \"https://...\", \"templated\" : \"...\"}\n    },\n    \"_embedded\": {\n        \"associated\": {\n            \"_links\": {\n                \"self\": { \"href\": \"https://...\" }\n            },\n            \"associatedProperty\": \"...\"\n        }\n    },\n    \"modelProperty\": \"...\"\n}\n```\n\nBoth will be supported for deserialization. Also if curie prefixes in the incoming document\nis chosen to be different from the prefixes in the POJO annotations deserialization will be\nsupported.\n\n## Serializing POJOs as HAL JSON\n\nSerialization is similar to the normal JSON serialization using the `HALMapper` instead of the\n`ObjectMapper`.\n\n```java\nObjectMapper halMapper = new HALMapper();\nString json = halMapper.writeValueAsString(new POJO());\n```\n\n## Deserializing POJOs from XML\n\nDeserialization is also similar to the normal JSON handling using the `HALMapper`.\n\n```java\nObjectMapper halMapper = new HALMapper();\nPOJO value = halMapper.readValue(\"{..json..}\", POJO.class);\n```\n\n## Using HAL Extension in JAX-RS Application\n\nTo use the HAL extension in a JAX-RS application you can add the [jackson-jaxrs-providers](https://github.com/FasterXML/jackson-jaxrs-providers) module\nto your application and use this to ensure the `HALMapper` is being used.\n\n```java\n@ApplicationPath(\"/\")\npublic class MyApplication extends Application {\n    private final Set\u003cObject\u003e singletons = new HashSet\u003c\u003e();\n\n    public MyApplication() {\n        singletons.add(new JacksonJsonProvider(new HALMapper()));\n    }\n\n    @Override\n    public Set\u003cObject\u003e getSingletons() {\n        return Collections.unmodifiableSet(singletons);\n    }\n}\n```\n\n## Using HAL Extension in JAX-RS Client\n\nUsing the HAL extension in a JAX-RS client works very similar to using it in an application. The\njackson-jaxrs-providers can be used to register the `HALMapper`.\n\n```java\nClientBuilder cb = ClientBuilder.newBuilder();\nClient client = cb.register(new JacksonJsonProvider(new HALMapper())).build();\n```\n## HALLink extended with temporal aspect\nThe HALLink is extended with a `seen` property. This is beyond the current specification of HAL.\nAn addendum or change to HAL will be proposed to incoorporate the seen property in the `_Link` specification.\nThe purpose of the `seen` property is to give consumers of a service the ability to judge for themselves whether\nthe last time a HAL related object was seen either as a `link` or as an `embedded` object.\n\n\n## Knows Limitations\n\nThe Wildfly application server comes with both a Jackson and Jackson 2 module which takes precedence\nover the ones registered with the JAX-RS client. Thus to make sure the HAL extension is actually\nused when creating a JAX-RS client running inside Wildfly you need to exclude the Jackson modules in\nthe `jboss-deployment-structure.xml` file.\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cjboss-deployment-structure\u003e\n    \u003cdeployment\u003e\n        \u003cexclusions\u003e\n            \u003cmodule name=\"org.jboss.resteasy.resteasy-jackson-provider\"/\u003e\n            \u003cmodule name=\"org.jboss.resteasy.resteasy-jackson2-provider\"/\u003e\n        \u003c/exclusions\u003e\n    \u003c/deployment\u003e\n\u003c/jboss-deployment-structure\u003e\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenapi-tools%2Fjackson-dataformat-hal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenapi-tools%2Fjackson-dataformat-hal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenapi-tools%2Fjackson-dataformat-hal/lists"}