Spotted Alternates Header in the Wild

September 1st, 2010

Just spotted an Alternates header in the wild:

$ curl http://www.w3.org -HAccept:text/foo -I
 
HTTP/1.1 406 Not Acceptable
Date: Tue, 31 Aug 2010 22:26:53 GMT
Server: Apache/2
Alternates: {"Home.html" 1 {type text/html} {charset utf-8} {length 28437}}, {"Home.xhtml" 0.99 {type application/xhtml+xml} {charset utf-8} {length 28437}}
Vary: negotiate,accept
TCN: list
Connection: close
Content-Type: text/html; charset=iso-8859-1

GET /stock-quote/foo vs. getStockQuote(“foo”)

August 24th, 2010

Consider the good old stock quote example from REST vs. RPC discussions. In both variants two kinds of coupling exist.

On the one hand there is the intentional coupling that causes the client to make the call to that particular remote thing and not just any arbitrary one. The intentional coupling is a human choice, manifested in configuration or code.

On the other hand there is technical coupling because the client software needs to know (aka be coupled to) the provided interface. Otherwise the communication would no be able to happen.

Given those two kinds or layers of coupling it makes no sense whatsoever to repeat the specifics already present in the intentional coupling at the technical level by giving that specific remote thing a specific interface.

Once the intentional choice has been made to talk to that remote thing the interface specifics can be factored away.

Why design, implement, test, maintain, document and explain more stuff if you can do the same things with less?

PUT and Content-Location

August 23rd, 2010

I noticed some days ago that I totally missed the use of the Content-Location header in responses to PUT requests. Used in this scenario, the client does not need an additional GET to obtain a representation of the resource after the PUT.

Caches can also cache the response of the PUT in this case.

PUT /foo
Content-Type: application/order
 
<order>
  <items>...</items>
</order>
 
200 Ok
Content-Location: /foo
Content-Type: application/order
ETag: "1"
 
<order>
  <status>accepted</status>
  <items>...</items>
</order>

The Content-Location header is telling the client: “This is the entity and entity headers you would receive for a GET to /foo”.

Amazingly Close

May 20th, 2010

While looking up some stuff in the book “Integration Patterns” I spotted a tiny sentence that is amazingly close to REST. In chapter one on page 3 the authors (among them Gregor Hohpe, BTW) emphasize that from the point of view of integration the whole must be considered instead of solely designing for each integration between two applications in turn. The sentence is

However, if you approach this same problem from an integration architecture perspective, the ideal application is a thin layer of presentation that consumes shared functionality or data at the enterprise level.

I find this amazingly close to the notion of a user agent component consuming representations and capabilities provided by resources.

IRC Conversation on User, User Agent, Media Types, Application etc.

May 6th, 2010

Currently I am trying to figure out the significance of the various aspects of a RESTful architecture with regard to modeling. Such aspects as user agent, media type, steady state, user, application, and application state. Tried to build-up an explanatory train of thought on that basis in an exchange with Philipp Meier on #rest IRC yesterday. It is the typical, hard to read, IRC conversation but you might find it useful nevertheless.

Jersey Client Side: The ViewResource Class

April 30th, 2010

The last posting in this introductory series provided a high level overview of the Jersey client side framework I am working on together with Paul. In this one, we look at some of the details.

At the heart of the framework lies the concept of ViewResources. Conceptually, ViewResources are an extension of the existing Jersey client side WebResource class. A ViewResource is a client side ‘handle’ for an HTTP resource through which HTTP requests to the resource can be performed. While WebResource ‘invocations’ result in ClientResponses or object representations of the response entities ‘invocations’ of ViewResources produce view objects that encapsulate assumptions (including anticipated next transitions).

The choice of view class for a given request completely expresses the assumptions made about the resource and the response. The view class in turn encapsulates these assumptions in a single artifact.

Regarding the examples that follow it is important to keep in mind that the view objects are not to be seen as local proxies for remote ‘objects’ but that the view objects hold application state and provide access to the data contained and a means to activate the controls that are (maybe) embedded in it.

In a subsequent installment of this introductory series we will see how even the entities of error responses constitute application state and can be used to construct corresponding views (possibly with contained application data and/or embedded controls for outgoing state transitions).

GET requests

URI poUri = URI.create("http://foo.org/purchaseOrders/42");
ViewResource vr = client.viewResource(poUri);
PurchaseOrderView pov = vr.get(PurchaseOrderView.class);

For GET requests there is a shorthand removing the need for an intermediate ViewResource object:

URI poUri = URI.create("http://foo.org/purchaseOrders/42");
PurchaseOrderView pov = client.view(poUri,PurchaseOrderView.class);

PUT requests

URI poUri = URI.create("http://foo.org/purchaseOrders/42");
ViewResource vr = client.viewResource(poUri);
PurchaseOrderView pov = vr.put(PurchaseOrderView.class, "some purchase order data");

For the use with PUT requests the build method of the PurchaseOrderView class could be implemented to work with both 200 Ok and 204 No Content responses. In the former case the body woud be interpreted as a representation of the order and in the latter the build method could perform an additional GET on the request URI to obtain a a representation of the order. We will discuss such support for automated transitions in a dedicated posting.

POST requests

URI colUri = URI.create("http://foo.org/purchaseOrders");
ViewResource vr = client.viewResource(colUri);
CreatedView<PurchaseOrderView> cv = new CreatedView(PurchaseOrderView.class);
vr.post(cv, "some purchase order data");
PurchaseOrderView newPoView = cv.getCreated();

This example makes use of the ‘helper’ view class CreatedView<T> provided with the framework. This view class encapsulates the HTTP mechanics related to 201 Created responses and makes the created resource retrievable as a view through the getCreated() method.

Note how this example instantiates the view class outside the framework and supplies the instance directly to the post() invocation.

DELETE requests

URI poUri = URI.create("http://foo.org/purchaseOrders/42");
ViewResource vr = client.viewResource(poUri);
VoidView vv = vr.delete(VoidView.class);

This example uses the framework supplied view class VoidView to handle the (possible empty) response to the DELETE request. Because the VoidView really does not express any kind of expectation its use outside the context of pure examples is rather useless.

Expectations pertaining to the context of a request should be encapsulated inside a view class and not be propagated into the code that actually uses the view. Deal with HTTP mechanics (such as checking response status) inside view classes.

A RESTful Client Side Framework for Jersey

April 29th, 2010

For the past couple of weeks Paul Sandoz and I have been working on a client side framework for Jersey that encourages RESTful design on the client side. After a trial period with frequent code changes, we feel that the code base is now stable enough to go public.

The framework introduces an annotation based approach that enables developers to turn arbitrary classes of the client side code into HTTP response handlers. The framework refers to instances of such classes as ‘views’ (mostly for the lack of a better term).

Views serve three purposes:

1. Build-up state corresponding to the handled response

View classes provide specifically annotated methods that will be invoked by the framework core to handle the response. These ‘build’ methods are intended to build-up the state of the view object from the HTTP response.

2. Present or make accessible the data of the current application state
Usually, users (human or machine) intend to use the information contained in HTTP response bodies. View objects make this information accessible either through GUI elements for human users or through access methods for machine users.

3. Use the hypermedia controls embedded in the response body to turn user (human or machine) actions into HTTP requests.

Both human and machine users interact with RESTful applications through user agent components by activating the controls embedded in the representations of the current application state. View objects provide a means for the user to activate the controls and will then create the corresponding HTTP requests. The means for control activation can be GUI elements in the case of human users or regular methods in the case of machine users.

Enough theory – let’s look at some code.

Suppose we want to develop a view class that is is suitable for Atom Publishing Protocol collections. The following examples step by step show the different aspects of such a view class and how it could be used.

First, we need a build method for handling HTTP success responses to GET requests to collection resources.

public class CollectionView {
 
	private Feed feed;
 
	@GET
	@Status(200)
	@Consumes("application/atom+xml")
	public void build(Feed feed) {
		this.feed = feed;
	}
}

The annotations on the build-method indicate to the framework core that the method applies to responses to GET requests that have a status of 200 Ok and a response body of the media type application/atom+xml. As requested by the method parameter list the framework core will inject the response body as a Feed object to enable access to the body inside the build method.

The code below shows how the CollectionView class might be used. The new view method on the Jersey Client class performs an HTTP GET on the provided URI, instantiates a new object of the provided class and then dispatches to a suitable build method of the created instances (based on the annotations).

public void main(String args[]) {
	URI uri = URI.create("http://example.org/blogs/jim/entries");
	Client client = new Client();
 
	CollectionView cv = client.view(uri, CollectionView.class);
}

Next we need to add to our CollectionView class methods that provide access to information contained in the feed. To keep things simple, we’ll just provide a getter for the title of the feed.

public class CollectionView {
 
	private Feed feed;
 
	@GET
	@Status(200)
	@Consumes("application/atom+xml")
	public void build(Feed feed) {
		this.feed = feed;
	}
 
	public String getFeedTitle() {
		return this.feed.getTitle();
	}
}

Example for using the getFeedTitle() method:

public void main(String args[]) {
	URI uri = URI.create("http://example.org/blogs/jim/entries");
	Client client = new Client();
 
	CollectionView cv = client.view(uri, CollectionView.class);
	System.out.println("Feed title is " + cv.getFeedTitle());
}

The third purpose of view classes mentioned above is to provide users (human or machine) with a means to activate the controls embedded in the response entities. RFC 5005 defines (among others) the ‘next’ link relation that can be used to tell a consumer of the feed document where the next page of the feed representation is located. We will use this link relation to demonstrate how a view class can expose a hypermedia control to the user.

One possibility to make ‘next’ links accessible to the user is to provide some getNextPageUri() method on the view class that can be called by the user to retrieve the URI of the next page. However, we can also provide a design that matches better the usual intent of the user of a feed: to iterate over the contained entries.

The code below shows an iterateEntries() method that processes all entries in the feed document of the view and follows any ‘next’ link to subsequent feed pages. The EntryHandler interface acts as a callback class.

public interface EntryHandler {
 
	public boolean handleEntry(Entry e);
 
}
public class CollectionView {
 
	private Client client;
	private Feed feed;
 
	@GET
	@Status(200)
	@Consumes("application/atom+xml")
	public void build(Feed feed, @Context Client client) {
		this.client = client;
		this.feed = feed;
	}
 
	public String getFeedTitle() {
		return this.feed.getTitle();
	}
 
	public void iterateEntries(EntryHandler entryHandler) {
 
		List<Entry> entries = this.feed.getEntries();
		for (Entry entry : entries) {
			boolean proceed = entryHandler.handleEntry(entry);
			if (!proceed) {
				return;
			}
		}
 
		Link link = this.feed.getLink("next");
		if (link == null) {
			return;
		}
 
		URI nextUri = link.getHref().toURI();
		CollectionView v = this.client.view(nextUri, CollectionView.class);
 
		v.iterateEntries(entryHandler);
	}
 
}

Note that we have added an annotated parameter to the build method to inject the client:

public void build(Feed feed, @Context Client client) {

This is necessary because the iterateEntries() method constructs a view for the next page if a ‘next’-link is found.

The CollectionView class can now be used to iterate over all entries in a feed as follows:

public void main(String args[]) {
	URI uri = URI.create("http://example.org/blogs/jim/entries");
	Client client = new Client();
 
	CollectionView cv = client.view(uri, CollectionView.class);
 
	 cv.iterateEntries(new EntryHandler() {
 
		private int count = 0;
 
		public boolean handleEntry(Entry entry) {
			this.count++;
			System.out.println("Entry #" + this.count + ": " + entry.getTitle());
 
			// limit the number of processed entries to 200
			return (this.count <= 200);
		}
	});
 
}

(You can find a similar example in the Jersey sources at experimental/view-client/jersey-view-client-samples/atompub-simple-view-client-sample)

The CollectionView example class demonstrates the three purposes of a view:

  • Handle HTTP responses
  • Present or make accessible application state
  • Provide a means for the user to activate hypermedia controls

Interactions with resources never occur without assumptions about the resources (for example that it is a Web page, an image or an Atom Publishing Protocol collection). View classes are manifestations of such assumptions and the choice of a specific view class for a given interaction expresses which assumptions are being made.

From a code structuring and maintenance perspective view classes nicely bundle up all the elements that pertain to such assumptions and act as a single point of documentation.

There are a number of issues we have not covered in this first blog. Among them are

  • Support for several response body media types
  • Error handling
  • Constructing requests other than GET
  • Performing a sequence of automated requests
  • Using ‘existing’ client side classes as view classes

We will talk about those and other features in follow up postings.

Instructions for Obtaining the Code

Unfortunately there are currently issues obtaining the latest SNAPSHOT artifacts from the java.net maven repository. Until this is resolved it is necessary to obtain and build Jersey yourself. The new client side framework is located in experimental/view-client.

Use SE 6 with maven version 2.2.0 or 2.2.1.

Join the Jersey project as an Observer at https://jersey.dev.java.net.

Check out the trunk source:


svn checkout \
https://jersey.dev.java.net/svn/jersey/trunk/jersey \
jersey --username <username>

Clean and install:

mvn clean install

If you want to do this a bit quicker you can skip the tests

mvn -Dmaven.test.skip=true clean install

You may need to set the following maven options (which can be set using the MAVEN_OPTS environment variable):

-Xmx1048m -XX:PermSize=64M -XX:MaxPermSize=128M

Discussion

Please send comments to the jersey users list.

Steady-State

April 4th, 2010

I have been meaning to write up for some time something about the notion of steady state. Now it ended up in a rest-duscuss posting.

Some references that I found insightful:

Slightly related from this blog: In Fear of Sub Requests.

Why ‘Action Resources’ are a REST Anti Pattern

March 31st, 2010

REST’s uniform interface constraint requires the operations that can be invoked on a resource to be generic, meaning that the applicability of an operation must not depend on the actual nature of the target resource. The uniform interface does not prohibit additional methods to be defined but requires any extension method to be generic. PATCH or MONITOR (slide 16) for example are valid extensions, while ORDER or PAY are not.

Our OO-biased brains are trained to think in terms of classes and associated operations (Cart.order()) and it apparently takes a considerable amount of time for our brains to re-wire and think in terms of transferring representations to modify resource state.

As a result, people are tempted to come up with ways to map non-uniform operations onto HTTP’s uniform interface. One offspring of such endeavor is the REST anti pattern of Action Resources.

I have not tracked it back to its origin, but the general form goes something like this:

Given an operation foo(), define a link semantic ‘foo’ that enables the server to tell the client what the URI is of ‘the foo-action resource of some other resource R. Knowing the foo-action resource Rfoo, the client would then be able to invoke the foo() operation on R by means of an empty POST to Rfoo:

Find foo-action resource of R:

HEAD /items/56
 
200 Ok
Link: </items/56/foo>;rel=foo

Invoke foo() on R:

POST /items/56/foo
Content-Length: 0
 
204 No Content

So, why am I calling it an anti pattern?

Action resources are an anti pattern because the approach violates REST’s self descriptive messages constraint. How so? Because the meaning of the POST request depends on resource state at the time the client learned that /items/56/foo is the foo-action resource of /items/56. There is nothing in the request that allows the server to understand the actual intention of the client at the time the server handles the POST request.

Suppose the client issues the above HEAD request at time T1, the server replies at T2 and the client receives the response at T3. By the time T4 the client sends the POST request to the action resource (and T5 when the server actually receives it) the server might have changed and is now looking at the POST with the empty body which translates to the client intention of telling the resource /items/56/foo to process this [empty body].

The server does not know that the request semantics depend on the server state at T2 when the server created the HEAD response and therefore cannot detect any mismatch between client intention and its own interpretation.

DELETE and 201 Created

March 7th, 2010

Just thought about a useful combination of DELETE and a 201 Created response:

DELETE /service/documents/667
 
201 Created
Location: /service/archive/documents/667
Content-Type: text/plain
 
Document /service/documents/667 has been deleted
and archived at /service/archive/documents/667.