<commit_before>= hydra-java image:https://travis-ci.org/dschulten/hydra-java.svg?branch=master["Build Status", link="https://travis-ci.org/dschulten/hydra-java"]
:toc:
:toc-placement: preamble

Annotate your Java beans and serialize them as http://www.w3.org/TR/json-ld/[json-ld] with http://www.hydra-cg.com/spec/latest/core/[hydra].

Status: Testing. Since the Hydra Specification is still a draft, expect incompatible changes.

Latest release: 0.3.1

== Problem

The meaning of json attributes in api responses, their possible values etc. is usually not obvious without referring to some 
information coming from outside the resource itself. That is due to the nature of json. Two solutions immediately come to mind. Both are ways of vendor-specific documentation, some are machine-readable, some aren't. 

Describe the type in some sort of json-schema, wadl, raml, swagger or similar and publish it together with the resource. People could even generate classes from this information, if they wish to. My api users coming from a wsdl background scream for something like that. 

Or put up documentation pages to describe your ex:doodad extension relation types and make the documentation available by dereferencing http://example.com/api/rels#doodad.

But one of the rules for a ReSTful API is:

[quote, Roy Fielding]
____
A REST API should never have “typed” resources that are significant to the client. 
Specification authors may use resource types for describing server implementation behind the interface, 
but those types must be irrelevant and invisible to the client. 
The only types that are significant to a client are the current representation’s media type and standardized relation names. 
[Failure here implies that clients are assuming a resource structure due to out-of band information, 
such as a domain-specific standard, which is the data-oriented equivalent to RPC's functional coupling].
____

My interpretation of this famous http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven[rant by <NAME>]:

A publicly available media-type should give clients all necessary means to interpret a server response, 
and relation names for hyperlinks in the response must be recognizable based on public conventions, so that the client can act upon
the responses it receives without knowing the details of a vendor-specific api.

In other words: If a client is told to make a reservation for a concert ticket, it should be able to recognize what 
one-fancy-api requires to achieve that without processing a vendor-specific documentation. How can we do that, purely based on a media type and relation names? Do we need hundreds of iana registered media types for all kinds of purposes?

== Solution (evolving)

I see http://www.w3.org/TR/json-ld/[json-ld] (media type application/ld+json) as a possible way to solve this problem without forcing people to ask me
about my vendor-specific documentation, thus decoupling the clients from my server types.

Clients should be able to understand a response based on widely available, standardized, public information.

The json-ld mediatype allows to bring descriptions of things in the real world from public vocabularies into your json files. With json-ld there *is* a way to say that a json response describes a http://schema.org/MusicEvent[MusicEvent] which http://schema.org/offers[offers] a http://schema.org/Ticket[Ticket] without any vendor-specific documentation, and it can also link to other resources.

A popular vocabulary which describes things on the internet is http://schema.org. It is used by all major search engines for search engine optimization and sufficient for basic needs. It also integrates with other vocabularies, 
e.g. by using http://schema.org/additionalType[additionalType] to point to http://purl.org/goodrelations/[GoodRelations] classes or by using external enumerated values as shown by http://schema.org/DeliveryMethod[DeliveryMethod].

(For those of you about to say that the Semantic Web never took off, please note that json-ld is http://manu.sporny.org/2014/json-ld-origins-2/[not about the Semantic Web at all]).

http://www.hydra-cg.com/[Hydra] adds interaction to the mix. It describes exactly how to post a ticket reservation.

So I want to add json-ld information to json objects serialized from my Java beans.

Java beans have no knowledge about the meaning of their bean properties and they do not know what they represent in the real world.

In the simplest possible case I want to design my json objects so that they can be understood by others based on schema.org.
By simply calling my json transfer class `Person` and letting it have an attribute `name`, I want to get a publicly understandable
json object, like this:

[source, Java]
----
    @Test
    public void testDefaultVocabIsRendered() throws Exception {

        class Person {
            private String name = "<NAME>";

            public String getName() {
                return name;
            }
        }

        mapper.writeValue(w, new Person());
    }
----

The corresponding json-ld object, written by hydra-java:

[source, Javascript]
----
{
  "@context": {
    "@vocab": "http://schema.org/"
  },
  "@type": "Person",
  "name": "<NAME>"
}
----

Note that I do not bind my clients to a server type `Person`. 
Rather, client and server are talking about the thing http://schema.org/Person[Person] as it is known and recognized by all major search engines.

For a more expressive example consider the json-ld example of http://schema.org/MusicEvent[MusicEvent], which shows how a ticket offering could look like.
	
In a more complex scenario I want to use my own attribute names and object design and still be able to use schema.org or other vocabs to describe their meaning. In json-ld I can. See below for a listing of vocabularies.

== First Steps
It is currently possible to render responses from a https://github.com/spring-projects/spring-hateoas[spring-hateoas] service based on Spring MVC with various message converters.

Look into the https://github.com/dschulten/hydra-java/blob/master/hydra-sample/service/src/main/java/de/escalon/hypermedia/sample/Config.java[sample configuration] to see how you can set up the hydra message converter, but also the XHTML message converter and the Siren message converter with Spring MVC.
The tests in https://github.com/dschulten/hydra-java/blob/master/hydra-jsonld/src/test/java/de/escalon/hypermedia/hydra/serialize/JacksonHydraSerializerTest.java[JacksonHydraSerializerTest] demonstrate the usage of `@Vocab`, `@Expose` and `@Term`.

== Features of hydra-spring
The conversion of a spring-hateoas Resource to hydra does the following:

- renders a spring-hateoas `List<Link>` in a `Resource<T>` in json-ld style
- renders spring-hateoas `Resources<T>` as `hydra:Collection`. If you use this feature, make sure you have a `@Term(define = "hydra", as = "http://www.w3.org/ns/hydra/core#")` annotation in your context.
- renders spring-hateoas `PagedResources<T>` as `hydra:Collection` with a `hydra:PartialCollectionView`. If you use this feature, make sure you have a `@Term(define = "hydra", as = "http://www.w3.org/ns/hydra/core#")` annotation in your context.
- renders response with `"@vocab" : "http://schema.org/"` by default, a different `@vocab` can be defined on a class or package using the `@Vocab` annotation.
- supports vocabularies in addition to the default vocabulary via terms in the `@context`. Use `@Term` in conjunction with `@Terms` on a class or package for this.
- renders `@type` based on the Java class name by default, a vocabulary class can be produced instead using `@Expose` on the Java class.
- renders attributes assuming that the attribute name is a property in the default vocab defined by `@vocab`. In other words, it renders an `offers` member as `"offers"` on a json-ld object with a context defining `"@vocab" : "http://schema.org"`, so that you end up with `"http://schema.org/offers"` as linked data name for your `offers` member. To map a custom attribute name such as `foo` to an existing property in the default vocab or other vocabs use `@Expose` on the attribute and a term will be created in `@context` which maps your attribute to the vocab property you set as value of `@Expose`.
- renders Java enums assuming that an enum value name is an enumerated value defined by the default vocab. In json-ld it is not only possible to have attribute names, but also attribute *values* that have linked data names. The idiom to express that is `"@type" : "@vocab"`. An example of this is http://schema.org/OnSitePickup[OnSitePickup], which is an enum value for the property http://schema.org/availableDeliveryMethod[availableDeliveryMethod]. If your Java enum value is ON_SITE_PICKUP, it matches the vocab value of OnSitePickup. It will be rendered as ON_SITE_PICKUP and hydra-java will add the necessary definition to the context which makes it clear that ON_SITE_PICKUP is actually `http://schema.org/OnSitePickup`. If your Java enum value has a different name than the vocab value, use `@Expose` on the enum value to get a correct representation in the context. Note that you can also expose an enum value from a different vocabulary such as GoodRelations, see below.

As of version 0.2.0 hydra-java supports hydra:collection, hydra:operation and hydra:IriTemplate as well as reversed terms. To make this possible, you *must* use the `linkTo` and `methodOn` methods of AffordanceBuilder as a drop-in replacement for `ControllerLinkBuilder`. Templated links created by ControllerLinkBuilder will at least be rendered as IriTemplates, but only with limited information about the template variables.

Furthermore, if you use these hydra features, make sure you have a `@Term(define = "hydra", as = "http://www.w3.org/ns/hydra/core#")` annotation in your context.

* renders a link to a remote collection as https://www.w3.org/community/hydra/wiki/Collection_Design[hydra:collection]. If you define the affordance to the remote collection with `AffordanceBuilder.rel()`, the remote collection gets a `hydra:subject` in its manages block, whereas if you define it with `reverseRel()` you get a `hydra:object`. To learn more about this design, consider the article https://www.w3.org/community/hydra/wiki/Collection_Design[Collection Design] in the hydra-cg wiki.
* renders a templated link as `hydra:IriTemplate`. Method parameters can be annotated with `@Expose` to assign them a property URI, otherwise the variable name will be shown as a term in the current vocab. If you create a link with AffordanceBuilder's linkTo-method facilities and you pass `null` for arguments annotated with `@PathVariable` or `@RequestParam`, it will automatically become a templated link with variables for the `null` arguments.
* renders a link to method handlers for any *combination* of GET, POST, PUT, PATCH and DELETE as `hydra:operation`. In order to express that multiple HTTP methods can be invoked on the same resource, use the `and()` method of AffordanceBuilder. See below for an example.
* renders a single, manually created, non-templated Link or Affordance in json-ld style.
* renders a POJO method parameter annotated with `@RequestBody` as expected rdfs:subClassOf. Use `@Expose` on the POJO class for a custom identifier. The setter methods on the bean appear as `hydra:supportedProperty`, and you can annotate them with `@Expose` to give them a semantic identifier. Again see below for an example.
* uses certain schema.org facilities to describe expected request bodies. For this we need schema.org either as `@vocab` or as a `schema:` term. If you do not use schema.org as `@vocab`, make sure you have a `@Term(define = "schema", as = "http://schema.org/")` in the context.
** expresses default value and value constraints by means of http://schema.org/PropertyValueSpecification. To specify such constraints, use the `@Input` annotation. Available constraints are min, max, step, minLength,  maxLength and pattern.
** expresses supported properties whose value is an object by nesting them via http://schema.org/rangeIncludes.


== Examples

=== Designing a Hydra API ===
See my article https://www.w3.org/community/hydra/wiki/Restbucks_with_Hydra for an example of an ordering flow. There is also a http://jbosswildfly-escalon.rhcloud.com/hypermedia-api/store[Sample Shop] which demonstrates the ideas from the article.

=== Live Demo

Use a ReST client to access a http://jbosswildfly-escalon.rhcloud.com/hypermedia-api/events[Sample Events API] to see the artifact hydra-sample at work. OpenShift sometimes completely shuts down the container, please try several times if you run into server errors when first accessing the sample.

Browsers will show the html representation of the API by default, which uses the `XhtmlResourceMessageConverter`. Sending `Accept: application/ld+json` will get you hydra, but `application/json` or `application/hal+json` work as well. 
When you POST or PUT, make sure you add a Content-Type header matching your request.


=== Exposing Java Bean Attributes

Assuming a Java enum whose enum values are exposed as values from GoodRelations and which appears on an Offer object with GoodRelations term:

The example shows a Java enum named `BusinessFunctionˋ whose enum values are exposed as values from GoodRelations. The enum appears on an Offer object with a GoodRelations term:

[source, Java]
----
    enum BusinessFunction {
        @Expose("gr:LeaseOut")
        RENT,
        @Expose("gr:Sell")
        FOR_SALE,
        @Expose("gr:Buy")
        BUY
    }
<commit_msg>moved sample projects URL into same section<commit_after>= hydra-java image:https://travis-ci.org/dschulten/hydra-java.svg?branch=master["Build Status", link="https://travis-ci.org/dschulten/hydra-java"]
:toc:
:toc-placement: preamble

Annotate your Java beans and serialize them as http://www.w3.org/TR/json-ld/[json-ld] with http://www.hydra-cg.com/spec/latest/core/[hydra].

Status: Testing. Since the Hydra Specification is still a draft, expect incompatible changes.

Latest release: 0.3.1

== Problem

The meaning of json attributes in api responses, their possible values etc. is usually not obvious without referring to some 
information coming from outside the resource itself. That is due to the nature of json. Two solutions immediately come to mind. Both are ways of vendor-specific documentation, some are machine-readable, some aren't. 

Describe the type in some sort of json-schema, wadl, raml, swagger or similar and publish it together with the resource. People could even generate classes from this information, if they wish to. My api users coming from a wsdl background scream for something like that. 

Or put up documentation pages to describe your ex:doodad extension relation types and make the documentation available by dereferencing http://example.com/api/rels#doodad.

But one of the rules for a ReSTful API is:

[quote, <NAME>ing]
____
A REST API should never have “typed” resources that are significant to the client. 
Specification authors may use resource types for describing server implementation behind the interface, 
but those types must be irrelevant and invisible to the client. 
The only types that are significant to a client are the current representation’s media type and standardized relation names. 
[Failure here implies that clients are assuming a resource structure due to out-of band information, 
such as a domain-specific standard, which is the data-oriented equivalent to RPC's functional coupling].
____

My interpretation of this famous http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven[rant by <NAME>ing]:

A publicly available media-type should give clients all necessary means to interpret a server response, 
and relation names for hyperlinks in the response must be recognizable based on public conventions, so that the client can act upon
the responses it receives without knowing the details of a vendor-specific api.

In other words: If a client is told to make a reservation for a concert ticket, it should be able to recognize what 
one-fancy-api requires to achieve that without processing a vendor-specific documentation. How can we do that, purely based on a media type and relation names? Do we need hundreds of iana registered media types for all kinds of purposes?

== Solution (evolving)

I see http://www.w3.org/TR/json-ld/[json-ld] (media type application/ld+json) as a possible way to solve this problem without forcing people to ask me
about my vendor-specific documentation, thus decoupling the clients from my server types.

Clients should be able to understand a response based on widely available, standardized, public information.

The json-ld mediatype allows to bring descriptions of things in the real world from public vocabularies into your json files. With json-ld there *is* a way to say that a json response describes a http://schema.org/MusicEvent[MusicEvent] which http://schema.org/offers[offers] a http://schema.org/Ticket[Ticket] without any vendor-specific documentation, and it can also link to other resources.

A popular vocabulary which describes things on the internet is http://schema.org. It is used by all major search engines for search engine optimization and sufficient for basic needs. It also integrates with other vocabularies, 
e.g. by using http://schema.org/additionalType[additionalType] to point to http://purl.org/goodrelations/[GoodRelations] classes or by using external enumerated values as shown by http://schema.org/DeliveryMethod[DeliveryMethod].

(For those of you about to say that the Semantic Web never took off, please note that json-ld is http://manu.sporny.org/2014/json-ld-origins-2/[not about the Semantic Web at all]).

http://www.hydra-cg.com/[Hydra] adds interaction to the mix. It describes exactly how to post a ticket reservation.

So I want to add json-ld information to json objects serialized from my Java beans.

Java beans have no knowledge about the meaning of their bean properties and they do not know what they represent in the real world.

In the simplest possible case I want to design my json objects so that they can be understood by others based on schema.org.
By simply calling my json transfer class `Person` and letting it have an attribute `name`, I want to get a publicly understandable
json object, like this:

[source, Java]
----
    @Test
    public void testDefaultVocabIsRendered() throws Exception {

        class Person {
            private String name = "<NAME>";

            public String getName() {
                return name;
            }
        }

        mapper.writeValue(w, new Person());
    }
----

The corresponding json-ld object, written by hydra-java:

[source, Javascript]
----
{
  "@context": {
    "@vocab": "http://schema.org/"
  },
  "@type": "Person",
  "name": "<NAME>"
}
----

Note that I do not bind my clients to a server type `Person`. 
Rather, client and server are talking about the thing http://schema.org/Person[Person] as it is known and recognized by all major search engines.

For a more expressive example consider the json-ld example of http://schema.org/MusicEvent[MusicEvent], which shows how a ticket offering could look like.
	
In a more complex scenario I want to use my own attribute names and object design and still be able to use schema.org or other vocabs to describe their meaning. In json-ld I can. See below for a listing of vocabularies.

== First Steps
It is currently possible to render responses from a https://github.com/spring-projects/spring-hateoas[spring-hateoas] service based on Spring MVC with various message converters.

Look into the https://github.com/dschulten/hydra-java/blob/master/hydra-sample/service/src/main/java/de/escalon/hypermedia/sample/Config.java[sample configuration] to see how you can set up the hydra message converter, but also the XHTML message converter and the Siren message converter with Spring MVC.
The tests in https://github.com/dschulten/hydra-java/blob/master/hydra-jsonld/src/test/java/de/escalon/hypermedia/hydra/serialize/JacksonHydraSerializerTest.java[JacksonHydraSerializerTest] demonstrate the usage of `@Vocab`, `@Expose` and `@Term`.

== Features of hydra-spring
The conversion of a spring-hateoas Resource to hydra does the following:

- renders a spring-hateoas `List<Link>` in a `Resource<T>` in json-ld style
- renders spring-hateoas `Resources<T>` as `hydra:Collection`. If you use this feature, make sure you have a `@Term(define = "hydra", as = "http://www.w3.org/ns/hydra/core#")` annotation in your context.
- renders spring-hateoas `PagedResources<T>` as `hydra:Collection` with a `hydra:PartialCollectionView`. If you use this feature, make sure you have a `@Term(define = "hydra", as = "http://www.w3.org/ns/hydra/core#")` annotation in your context.
- renders response with `"@vocab" : "http://schema.org/"` by default, a different `@vocab` can be defined on a class or package using the `@Vocab` annotation.
- supports vocabularies in addition to the default vocabulary via terms in the `@context`. Use `@Term` in conjunction with `@Terms` on a class or package for this.
- renders `@type` based on the Java class name by default, a vocabulary class can be produced instead using `@Expose` on the Java class.
- renders attributes assuming that the attribute name is a property in the default vocab defined by `@vocab`. In other words, it renders an `offers` member as `"offers"` on a json-ld object with a context defining `"@vocab" : "http://schema.org"`, so that you end up with `"http://schema.org/offers"` as linked data name for your `offers` member. To map a custom attribute name such as `foo` to an existing property in the default vocab or other vocabs use `@Expose` on the attribute and a term will be created in `@context` which maps your attribute to the vocab property you set as value of `@Expose`.
- renders Java enums assuming that an enum value name is an enumerated value defined by the default vocab. In json-ld it is not only possible to have attribute names, but also attribute *values* that have linked data names. The idiom to express that is `"@type" : "@vocab"`. An example of this is http://schema.org/OnSitePickup[OnSitePickup], which is an enum value for the property http://schema.org/availableDeliveryMethod[availableDeliveryMethod]. If your Java enum value is ON_SITE_PICKUP, it matches the vocab value of OnSitePickup. It will be rendered as ON_SITE_PICKUP and hydra-java will add the necessary definition to the context which makes it clear that ON_SITE_PICKUP is actually `http://schema.org/OnSitePickup`. If your Java enum value has a different name than the vocab value, use `@Expose` on the enum value to get a correct representation in the context. Note that you can also expose an enum value from a different vocabulary such as GoodRelations, see below.

As of version 0.2.0 hydra-java supports hydra:collection, hydra:operation and hydra:IriTemplate as well as reversed terms. To make this possible, you *must* use the `linkTo` and `methodOn` methods of AffordanceBuilder as a drop-in replacement for `ControllerLinkBuilder`. Templated links created by ControllerLinkBuilder will at least be rendered as IriTemplates, but only with limited information about the template variables.

Furthermore, if you use these hydra features, make sure you have a `@Term(define = "hydra", as = "http://www.w3.org/ns/hydra/core#")` annotation in your context.

* renders a link to a remote collection as https://www.w3.org/community/hydra/wiki/Collection_Design[hydra:collection]. If you define the affordance to the remote collection with `AffordanceBuilder.rel()`, the remote collection gets a `hydra:subject` in its manages block, whereas if you define it with `reverseRel()` you get a `hydra:object`. To learn more about this design, consider the article https://www.w3.org/community/hydra/wiki/Collection_Design[Collection Design] in the hydra-cg wiki.
* renders a templated link as `hydra:IriTemplate`. Method parameters can be annotated with `@Expose` to assign them a property URI, otherwise the variable name will be shown as a term in the current vocab. If you create a link with AffordanceBuilder's linkTo-method facilities and you pass `null` for arguments annotated with `@PathVariable` or `@RequestParam`, it will automatically become a templated link with variables for the `null` arguments.
* renders a link to method handlers for any *combination* of GET, POST, PUT, PATCH and DELETE as `hydra:operation`. In order to express that multiple HTTP methods can be invoked on the same resource, use the `and()` method of AffordanceBuilder. See below for an example.
* renders a single, manually created, non-templated Link or Affordance in json-ld style.
* renders a POJO method parameter annotated with `@RequestBody` as expected rdfs:subClassOf. Use `@Expose` on the POJO class for a custom identifier. The setter methods on the bean appear as `hydra:supportedProperty`, and you can annotate them with `@Expose` to give them a semantic identifier. Again see below for an example.
* uses certain schema.org facilities to describe expected request bodies. For this we need schema.org either as `@vocab` or as a `schema:` term. If you do not use schema.org as `@vocab`, make sure you have a `@Term(define = "schema", as = "http://schema.org/")` in the context.
** expresses default value and value constraints by means of http://schema.org/PropertyValueSpecification. To specify such constraints, use the `@Input` annotation. Available constraints are min, max, step, minLength,  maxLength and pattern.
** expresses supported properties whose value is an object by nesting them via http://schema.org/rangeIncludes.


== Examples

=== Designing a Hydra API ===
See my article https://www.w3.org/community/hydra/wiki/Restbucks_with_Hydra[Restbucks with Hydra] for an example of an ordering flow.

=== Live Demo

Use a ReST client to access a http://jbosswildfly-escalon.rhcloud.com/hypermedia-api/events[Sample Events API] to see the artifact hydra-sample at work.
There is also a http://jbosswildfly-escalon.rhcloud.com/hypermedia-api/store[Sample Shop] which demonstrates the ideas from the Restbucks with Hydra article.
OpenShift sometimes completely shuts down the container, please try several times if you run into server errors when first accessing the sample.

Browsers will show the html representation of the API by default, which uses the `XhtmlResourceMessageConverter`. Sending `Accept: application/ld+json` will get you hydra, but `application/json` or `application/hal+json` work as well. 
When you POST or PUT, make sure you add a Content-Type header matching your request.


=== Exposing Java Bean Attributes

Assuming a Java enum whose enum values are exposed as values from GoodRelations and which appears on an Offer object with GoodRelations term:

The example shows a Java enum named `BusinessFunctionˋ whose enum values are exposed as values from GoodRelations. The enum appears on an Offer object with a GoodRelations term:

[source, Java]
----
    enum BusinessFunction {
        @Expose("gr:LeaseOut")
        RENT,
        @Expose("gr:Sell")
        FOR_SALE,
        @Expose("gr:Buy")
        BUY
    }

{'fraction_non_alphanumeric': 0.07467449110581331, 'fraction_numerical': 0.001687144690995782, 'mean_word_length': 4.413142743696644, 'pattern_counts': {'":': 8, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 16, 'lorem ipsum': 0, 'www.': 20, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6150562', 'n_tokens_mistral': 7442, 'n_tokens_neox': 7079, 'n_words': 3612}