Sunday, March 10, 2013

QCon London 2013

I was fortunate enough to attend QCon London this year courtesy of Black Pepper. Out of the many interesting sessions, a series of talks centred around Web application architecture and REST particularly caught my imagination.

Stefan Tilkov began by holding a mirror up to the modern webapp architecture in his talk, "Web Development: You're Doing it Wrong". He outlined a number of typical UI smells, such as the back button not working as expected and the inability to open multiple windows, that indicate that perhaps your architecture is fighting the model of the web. These problems tend to arise when we use a higher-level web framework to abstract ourselves away from the underlying web technologies (HTML, CSS, JavaScript) and the properties of HTTP (statelessness, client-server). Stefan argued that by attempting to overcome these problems, web frameworks ultimately evolve into primitive web-like architectures that foolishly try to re-solve the problems that the web itself has already solved. It's much easier to work with the web rather than fight against it.

Stefan proposed a hybrid style between traditional server-side UI components and modern single-page applications (SPA) that takes the best characteristics of each, which he dubbed 'Resource-Orientated Client Architecture' (ROCA). ROCA is a set of recommendations that describe how your application can be of the web, rather than just on the web. Central to this style is the subtle concept that the UI becomes merely a semantic HTML representation of its RESTful service.

Rickard Öberg complimented these ideas in his talk, "Road to REST". He described the design evolution of a RESTful service that provided the back-end to various client platforms. The lessons learnt were two-fold: firstly, the resources exposed by the service should correlate to use-cases, rather than entities; and secondly, the often neglected HATEOAS constraint of REST allows clients to discover, and adapt to, server changes. Embracing these ideas again blurs the boundary between RESTful services and their UI, or as Rickard aptly put it, "a good REST API is like an ugly website".

Taking this concept further was Jon Moore in his talk, "Building Hypermedia APIs with HTML", where he proposed using HTML itself as the hypermedia representation for RESTful services. This approach has many advantages over JSON or other XML representations, for example: web browsers implicitly become clients of your API; HTML already has comprehensive hypermedia support; and HTML5 provides semantic metadata in the form of HTML Microdata. He demonstrated a simple command line tool that was able to programmatically explore and use any REST API written to these principals, much like a user can navigate any website. Once again we witness the trend of unifying human and computer interaction with web services.

Looking into the future, Mike Amundsen hypothesised how these ideas may evolve in his talk, "Generic Hypermedia and Domain-Specific APIs: RESTing in the ALPS". He highlighted concern over the recent explosion in web service APIs, specifically as they tend to be proprietary rather than domain-specific. For example, there are hundreds of shopping APIs but there is no single standardised API to access them all through. Mike proposed that we need a common language to standardise domain-specific APIs, much like schema.org does for domain-specific data, which he calls Application-Level Profile Semantics (ALPS). It is very much a work-in-progress but it has great potential to take us towards the fabled semantic web.

Sunday, February 12, 2012

Varargs Runtime Type Tokens

A common pattern for accessing generic type information in Java at runtime is to use class literals as runtime type tokens. For example, consider the following generic interface:

public interface Factory<T>
{
    T make() throws Exception;
}

We can implement this using class literals to access T at runtime even though this information is erased at compile time:

public class ClassLiteralFactory<T> implements Factory<T>
{
    private final Class<T> type;
    
    public ClassLiteralFactory(Class<T> type)
    {
        this.type = type;
    }
    
    public T make() throws Exception
    {
        return type.newInstance();
    }
}

This allows us to create a Factory for any object with a default constructor by supplying the corresponding class literal:

Factory<Date> factory = new ClassLiteralFactory<Date>(
    Date.class);
Date date = factory.make();

All rather straightforward so far, but can we implement this interface without requiring an explicit class literal? It turns out that we can, by using varargs:

public class VarArgsFactory<T> implements Factory<T>
{
    private final Class<? extends T> type;
    
    public VarArgsFactory(T... type)
    {
        this.type = (Class<? extends T>) type.getClass()
            .getComponentType();
    }
    
    public T make() throws Exception
    {
        return type.newInstance();
    }
}

The trick here is to take advantage of the code generated by the compiler when invoking a varargs method. For example, when we write:

Factory<Date> factory = new VarArgsFactory<Date>();

The compiler actually generates the following:

Factory<Date> factory = new VarArgsFactory<Date>(
    new Date[0]);

This empty array then allows us to obtain a class literal as we did previously. The subtle difference with this technique, though, is that we can only guarantee Class<? extends T> as opposed to Class<T> due to the covariant nature of Java arrays. For instance, we could legitimately write:

Factory<Date> factory = new VarArgsFactory<Date>(
    new Timestamp[0]);

Which would happily become a factory for the Date subclass java.sql.Timestamp (if it had a default constructor). Note that ClassLiteralFactory does not suffer from this problem because Timestamp.class would be an invalid argument for the Class<Date> parameter since parameterized types are invariant.

So can we rationalise the unchecked cast in the constructor? Strictly speaking, all the compiler can guarantee for the class of type is Class<? extends Object[]>, since Object[] is the erasure of T[]. Although, in this case, our constructor is not annotated with @SafeVarargs so we can safely assume that T is a reifiable type, otherwise the caller would encounter an unchecked warning and type safety would no longer be guaranteed. This provides the justification to cast type to Class<? extends T[]> and hence its component type to Class<? extends T>.

Considering the case when T is non-reifiable leads us to discover some interesting benefits of this pattern over class literals. For example, if we annotated the constructor with @SafeVarargs then our factory can also support parameterized types:

Factory<ArrayList<Date>> factory =
    new VarArgsFactory<ArrayList<Date>>();
ArrayList<Date> dates = factory.make();

Here, the actual type argument ArrayList<Date> is erased to the raw type ArrayList to create the vararg, then instantiated, and essentially cast back to ArrayList<Date>. This is type safe since all generic instantiations share the same raw type. Note that by allowing non-reifiable types like this means that we should revisit how the runtime type token is declared. Because the raw type is a supertype of its generic subtypes, the runtime type token now becomes Class<? extends ? super T> which can only be safely declared as Class<?>. This has the unfortunate consequence that each use of the runtime type token must rationalise its own unchecked warning.

One caveat of allowing non-reifiable types is that they can violate type safety when type variables are used. For instance, the following method will always return an Object instance irrespective of the actual type argument specified:

public <T> T unsafeMake()
{
    return new VarArgsFactory<T>().make();
}

So the following will throw a ClassCastException:

Date date = unsafeMake();

Still, the benefits of supporting parameterized types may outweigh these drawbacks if they are clearly documented.

In conclusion, the advantages of the varargs pattern for runtime type tokens over class literals are: less boilerplate code since no class literal is required; and parameterized types can be supported to a degree. Its disadvantages are: an upper-bounded runtime type token restricts use; and type safety can be violated when non-reifiable type support is required. Nevertheless, it's a useful trick to keep up an API designer's sleeve.