Structural linking with Jersey + Moxy – an AspectJ solution

The requirement

In a REST resource representation, structural links can be embedded in the resource to allow the client to navigate to subresources. This is in contrast to so-called transitional links, which represent state transitions.

    <parent id="100">
        <!-- I am a transitional link -->
        <link href="http://myserver/parents/100" rel="delete">  

        <!-- We are child resources with structural links to our full representation -->
        <child id="1" href="http://myserver/children/1"/>       
        <child id="2" href="http://myserver/children/2"/>

The JAX-RS project has a good discussion of the differences, as well as some explanation of why transitional links are so much easier to support than structural links.

I’ve been struggling to find a good way to implement structural links, especially as I want to add a couple more constraints:

  1. The domain model must not be touched. Even when you do have access to the source code, I simply don’t think it’s kosher to pollute a domain model with cross-cutting concerns like serialization to a particular format.
  2. I won’t put up with death-by-boilerplate, such as creating a DTO for each domain model class.

I posted this problem as a Stack Overflow question along with some candidate approaches. This blog post is about the first candidate, the AspectJ solution.

The solution sketch

This solution uses Jersey’s very handy declarative linking capability. You can add a field to a model class and Jersey will populate it for you. Even more impressively, you can simply point Jersey at a method in your REST API and Jersey will derive your link from the @Path annotations on that method. Too easy. Just too bad this violates my #1 constraint, that the model not be touched.

Enter AspectJ. We can use an intertype declaration to add the field, and everything just works.

The downside of this solution is that the structural link configuration is not truly externalized (with respect to the model). Yes, we’ve avoided altering the model source code – which, IMHO, is no small win, as preserving the expressive power of the model source code is a pretty high priority for me. However, at the byte code level, we have most definitely altered the model, at least within this compilation unit. The new fields will be visible to any reflection-driven framework and may pop up in other representations. If we can live with that, this is a pretty clean solution.

Example code

This code is also available on BitBucket.

Model classes

package testing;

import java.util.ArrayList;
import java.util.List;

public class Planet {

    private int id = 1;
    private String name = "test";
    private double radius = 3.0;

    private List<Moon> moons = new ArrayList<Moon>(0);
    public void addMoon(Moon moon) {
package testing;

public class Moon {
	private String name;
	// No-arg constructor is a requirement of JAXB
	public Moon() {
	public Moon(String name) { = name;
	public String getName() {
		return name;


Resource class

For the proof-of-concept, we’re just serving an freshly created instance of the model.

package testing;


public class Services {
	private Planet initPlanet() {
		Planet p = new Planet();
		p.addMoon(new Moon("moon1"));
		p.addMoon(new Moon("moon2"));
		return p;

	public Planet planet () {
		return initPlanet();
	@GET @Path("/moons/{moonid}")
	public Moon moon (@PathParam("moonid") String name) {
		return new Moon(name);

Jersey configuration


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="" xmlns="" xsi:schemaLocation="" id="WebApp_ID" version="3.0">
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-name>Jersey REST Service</servlet-name>

Application class

This is the class pointed to by the web.xml, and it really just exists so we can register the declarative linking feature.

package testing;

import org.glassfish.jersey.linking.DeclarativeLinkingFeature;
import org.glassfish.jersey.server.ResourceConfig;

public class MyApplication extends ResourceConfig {
    public MyApplication() {


Moxy configuration

Moxy’s ability to configure JAXB mappings entirely from an external file is a cornerstone of my approach to serving up unmodified domain objects.

This is how we let Jersey know we want to use Moxy as the JAXB provider.


The moxy mapping file, planets.oxm.xml

Note that the href elements mentioned in the mapping file do not exist in the model source code.

<?xml version="1.0"?>
        <java-type name="Planet">
	           	<xml-attribute java-attribute="href"/>
                <xml-element java-attribute="name"/>
                <xml-element java-attribute="radius"/>
 				<xml-element java-attribute="moons" name="moon">
 					<xml-element-wrapper name="moons"/>
        <java-type name="Moon">
	           	<xml-attribute java-attribute="href"/>
        		<xml-element java-attribute="name"/>

Moxy context resolver

This is how we supply Moxy with the correct mapping file. The @Provider annotation lets Jersey automatically find our context resolver.

package testing;

import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class MyMoxyContextResolver implements ContextResolver<JAXBContext> {
    private JAXBContext context = null;
    public JAXBContext getContext(Class<?> type) {
	System.out.println("Invoking MyMoxyContextResolver.getContext");
    	if (context == null || context != null) {
	        try {
	        	System.out.println("MyMoxyContextResolver - Creating new JAXBContext");
	            Map<String, Object> properties = new HashMap<String, Object>(1);
	            properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "testing/planets.oxm.xml");
	            context = JAXBContext.newInstance(new Class[] {Planet.class}, properties);
	        } catch(JAXBException e) {
	            throw new RuntimeException(e);
       return context;


Custom MessageBodyWriter

As per this StackOverflow question, we need to add a custom MessageBodyWriter to convince Jersey to marshall a completely unannotated model. Again, Jersey picks this up automatically.

package testing;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class MyMessageBodyWriter implements MessageBodyWriter<Object> {

	protected Providers providers;

    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return true;
    public long getSize(Object les, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return -1;
    public void writeTo(Object les, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
        try {
        	ContextResolver<JAXBContext> resolver = providers.getContextResolver(JAXBContext.class, mediaType);
        	JAXBContext context = resolver.getContext(type);
        	Marshaller m = context.createMarshaller();
			m.marshal(les, entityStream);

        } catch (JAXBException e) {

The aspect

This is what makes it all work. As this project is laid out all in one package, all you need to do is compile with the AspectJ compiler and this aspect will be woven into the model classes. In a more realistic project, you’d have the model classes on the inpath and this aspect on the aspectpath.

package testing;

import org.glassfish.jersey.linking.InjectLink;
import org.glassfish.jersey.linking.Binding;

public aspect HrefInjector {
	private String Planet.href;
	declare @field : * Planet.href : @InjectLink(
									) ;

	private String Moon.href;
	declare @field : * Moon.href : @InjectLink(
												name="moonid", value="${}"
									) ;


Project layout

Screenshot from 2014-06-27 16:40:30

(click to enlarge)


As they appear in the gradle build file:

dependencies {
   compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.9'
   compile ''
   compile 'org.glassfish.jersey.ext:jersey-declarative-linking:2.9'
   providedCompile 'javax.servlet:servlet-api:2.5'

As always, you can run

./gradlew dependencies

to see the full list of transitive dependencies.

Sample output


	<planet href="http://localhost:8080/reststructlinks/rest/services">
			<moon href="http://localhost:8080/reststructlinks/rest/services/moons/moon1">
			<moon href="http://localhost:8080/reststructlinks/rest/services/moons/moon2">


  "href": "http://localhost:8080/reststructlinks/rest/services",
  "name": "test",
  "radius": 3,
  "moons": {
    "moon": [
        "href": "http://localhost:8080/reststructlinks/rest/services/moons/moon1",
        "name": "moon1"
        "href": "http://localhost:8080/reststructlinks/rest/services/moons/moon2",
        "name": "moon2"


A few concluding comments:

  1. There are only two source files concerned with structural linking – the mapping file, and the aspect. The rest of the system operates exactly as per usual. This satisifies the requirement for structural linking to be separated out as a crosscutting concern.
  2. It’s entirely appropriate that the mapping file is involved, as it means you can control when and where you want the structural links by modifying the mapping file.
  3. The aspect requires no special configuration, as it is using bog-standard built-in Jersey functionality.
  4. Jersey’s built-in UriBuilder approach to transitional linking co-exists happily with this aspect-driven approach.
  5. Of course, some people/projects are allergic to AspectJ for whatever reason, so it would still be good to see another candidate solution emerge.

Hope this helps!

Unconfuse yourself about REST, HATEOAS, and API design

I set out to create a simple REST API about a week ago. Having got a basic proof of concept working, I thought I’d look up the accepted wisdom on API design. Well! After a couple of days hacking through the seething jungle of opinion, holy wars and plain misinformation, I now realize it might be a little too soon for “accepted”. However, there were three things I found after much labour that really helped clarify my thinking, so I thought I’d call those out here.

Roy Fielding’s semi-rant on the hypermedia constraint

This article opened my eyes to the larger issues that REST was originally designed to address. It also is a handy test – if, like me, you find that much of the terminology in this article is unfamiliar, that’s a good sign that you haven’t really engaged with the work that’s been done on those issues. Knowing what you don’t know is always a good thing.

There’s a lot of nonsense not particularly useful stuff out there in the blogosphere about API discoverability, with the proponents struggling to come up with a really convincing benefit, and the opponents holding up the chimera of completely automated discoverability by a completely generic automaton as a kind of reductio ad absurdum. Fielding makes it clear that, while the automaton might be nice if you can afford to build it, a discoverable API is just as important for that most ubiquitous of generic user agents, the next generation of application programmers.

“REST is software design on the scale of decades: every detail is intended to promote software longevity and independent evolution.” – Roy Fielding, comment #8

What’s a media type and how do you create one?

Two things become clear in the comment stream from the above article (and other sources):

  1. Fielding sees “out-of-band” information (that is, the stuff that the parties in a client-server interaction have to know that is not contained within the interaction itself) as a threat to API longevity
  2. More importantly, and apparently not widely understood, Fielding doesn’t see the media type definition as being out-of-band. In fact it’s the media type definition that saves you from needing out-of-band information.

So what’s a media type and how do you create one? This is apparently widely misunderstood (including by me), and it’s surprisingly hard to find a simple answer.

In fact, there is a very simple answer. A media type is an information standard. You create one by writing it down. You can share it globally by registering it with IANA. The MIME types with which we are all familiar are simply pointers to this registry. Or, you can share it locally by just telling your mates where the standards document is. Here’s an incredibly simple example.

Again, the waters are muddied by people leaping immediately to the most difficult case, that of automatic discovery by generic automatons. If your “user agents” are developers, all you need in your media type documentation is human-readable text.

How to design a mashup

You can’t, of course. That’s the point of a mashup. You just “expose” some information and the genius of the crowd will then mash it together with other things in ways that you couldn’t possibly imagine, right? Hands-up everyone who thought that designing REST APIs is about exposing information (I have both hands up at this point). Unfortunately, this is utter nonsense, and even more unfortunately it doesn’t take much thinking to see that it’s nonsense. Who really believes that Google didn’t know people would be embedding maps with pins on them?

Fortunately, the talented guys at Jayway wrote a very nice article called Why hypermedia APIs? which reminded me that designing API’s is very closely related to designing applications (remember what the “A” and the “P” in API stand for?).

Designing applications starting with use cases is something I know how to do. Of course it’s blindingly obvious that API’s must also be designed with use cases in mind, but I had allowed myself to be almost terminally distracted by the mashup rhetoric along with with an abundance of bad examples.


Those were my three biggest pain points, which I’ll just restate here for easy access:

  1. What on earth is this HATEOAS stuff all about and what does it mean for my design?
  2. What’s a media type (really)
  3. How do I design something that will be used in “limitless and unimaginable ways”?

The resources I’ve pointed to in this post were invaluable in unconfusing me, so I hope they’ll help you too.