Thursday, October 6, 2011

JavaOne 2011: REST and Hypermedia as the Engine of Application State with Standard Java APIs

For my last technical session of JavaOne 2011, I wanted to attend something "easy" with a short title because of the mental fatigue and crammed brain resulting from four days of blistering rate of technical information coming my way. With that in mind, I chose to walk across the hall from Hilton San Francisco's Golden Gate 6/7/8 to Golden Gate 3/4/5 for the presentation "REST and Hypermedia as the Engine of State with Standard Java APIs" (24609). Although I have worked with REST and JAX-RS/Jersey, the abstract of this presentation caught my eye. In addition, I believe that HATEOAS may be the least understood, most confusing, and most misused term (or unused portion) in all of REST-dom.

The presenters of "REST and HATEOAS with Standard Java APIs" (Mattias Hellborg Arthursson and Kalle Stenflo, both from Jayway) stayed away from using the acronym HATEOAS because no one seems to know how to pronounce. Because I'm typing it rather than saying it, I'm using the abbreviation from here on out. Their agenda showed items to be covered including REST, JAX-RS, RESTful JAX-RS ("true REST with hypermedia"), and "Generic JavaScript Client."

Stenflo briefly discussed the history of REST based on Fielding's famous dissertation. He mentioned that the "architectural style" of REST had been misused and hijacked by several to be a structural style. Stenflo then went on to discuss the basics of REST with definitions of terms like "resource." He also discussed the HTTP "verbs" and stated that "REST is about using the web the way it was intended." Stenflo discussed "self-descriptive messages" that "contain all information needed to complete a task" (this statelessness is what makes horizontal scaling easier).

Stenflo had multiple slides titled "HATEOAS: Hypermedia as the Engine of Application State." This concept allows for "discoverable resource interaction" and "allows resources to evolve over time." Stenflo explained that the consumer is provided with the correct link for a given resource.

Arthursson stated that if you're doing REST with Java, "you should probably be using JAX-RS." Arthursson introduced some of the key annotations that JAX-RS provides such as @Path, @GET, @POST, @PUT, and @DELETE. He feels (as do I) that the JAX-RS is one of the best JSRs in recent years. The Expert Group for JAX-RS 2.0 is about to publish a draft and the new version will focus on improvements requested from the community. These features include a common client API (that would be very nice) and "support for hypermedia" (JAX-RS currently does not support HATEOAS)

Until JAX-RS 2.0 implementations are available (and the spec is not even written yet!), we need a way to handle hypermedia in Java-based REST style applications. Arthursson introduced some approaches from RESTeasy Atom link, Jersey linking, and "purely annotation-based" approaches that are "more readable, "more versatile," and require DTOs to have "knowledge of hypermedia." His understanding is that the JSR Expert Group is leaning toward the annotation-based approach as well.

Arthursson introduced jax-rs-hateoas as an open source JAX-RS 1.x extension. The README for jax-rs-hateoas states:

JAX-RS-HATEOAS is a small extension to JAX-RS to enable hypermedia in JAX-RS 1.x applications.

Adding hypermedia to your existing application is easily done in four steps:
* Extend HateoasApplication (or JerseyHateoasApplication)
* Add a RequestContextFilter in your web.xml (enables the framework to get access to the full request URIs)
* Add @Linkable annotations to all methods that should be linkable.
* Use HateoasResponse instead for building responses with HATEOAS links.
The normal Response methods (ok, created, entity, etc.) will now return a HateoasResponseBuilder.
The HateoasResponseBuilder contains methods to easily add links to your responses:
** link(String linkId, Object... params) - adds a link to the referenced linkId
(as defined by an @Linkable annotation).
** selfLink(String linkId, Object... params) - adds a link to the referenced linkId with a 'self' rel
(rather than the default rel defined in the referenced @Linkable annotation
** ...etc

Arthursson covered these steps in his slides and then moved to an IDE (SpringSource Tool Suite) to show a live example. His examples demonstrated the ability to use @Linkable from jax-rs-hateoas to provide hypermedia in responses (such as HateoasResponse). The jax-rs-hateoas project seems pretty easy to use and it was stated that it's pretty small and is designed to allow developers to customize their hypermedia as necessary.

Following Arthursson's IDE-based demonstration, Stenflo took back over to demonstrate a JavaScript client that is a "single-page JavaScript application." He stated that it's useful for a developer to test out his or her REST API. The demonstrated client works on hypermedia returned to the client.

The speakers referenced several projects that attendees might find useful in Jayway's Github respository. They specifically referenced rest-assured in addition to jax-rs-hateoas and also stated that the demonstrated JavaScript client is available in the demos section (there is also a core download).

A good question was whether XML was supported in jax-rs-hateoas (only JSON was demonstrated). At this point, only JSON (the "cool stuff") is supported, but they acknowledged that XML needs to be supported.

This was an interesting presentation and looks like a promising solution for bridging the gap between today and JAX-RS 2.0 in terms of appropriately using HATEOAS in REST-based applications using JAX-RS. The project is still young, but could end up filling a niche in the Java/REST world. In the end, it's likely that JAX-RS 2.0 will make this obsolete, but that could be years from now.

2 comments:

@DustinMarx said...

The PDF slides of this presentation are now available.

Bryce said...

Such an approach would be a complementary feature to JMX based administration, we could use it to report chache performance, eventually Feature Toggle, etc. And with a light weight client.

This is interesting!