A Hypermedia Framework?

Earlier today, Jim and I were discussing the structure and content of our "Hypermedia Services" chapter for our book (tentatively titled "GET /Connected"). The book is getting along really nicely. I think we are way beyond mid-point, dare I say 3/4 of the way? 🙂

A new idea about a pattern popped up during our chat. We both agreed that no one is currently making use of such a pattern (or, better... no one that we know of 🙂 so we weren't sure whether we should dedicate any space in our chapter to discuss it. Furthermore, there might be some technical issues with the pattern that might not be obvious to us. We decided that we should reach out to the community to test the idea and also to get a feel on whether it has a place on a book about Web-based integration.

In our "How to GET a Cup of Coffee" article, we showed how the "hypermedia as the engine of application state" could be used in a machine-to-machine integration scenario. In the book, we expand a lot more on that idea.

In our Restbucks world (the example we use throughout the book), we have order resources with which consuming applications can interact. We use atom:link elements as part of a resource's state representation to indicate the expected next steps in an interaction. For example, when a customer GETs the state representation of a particular order (e.g. http://restbucks.com/order/1234), the following representation will be probably returned as the content of an HTTP/1.1 200 OK response.

         1: <order xmlns="http://restbucks.com" xlmns:atom="http://www.w3.org/2005/Atom">
         2:   <consume-at>takeAway</consume-at>
         3:   <item>
         4:     <name>latte</name>
         5:     <quantity>1</quantity>
         6:     <milk>whole</milk>
         7:     <size>small</size>
         8:   </item>
         9:   <received>2009-02-26 12:07</received>
        10:   <amount>10.00</amount>
        11:   <currency>GBP</currency>
        12:   <atom:link rel="payment" type="application/vnd.restbucks+xml" href="http://restbucks.com/order/1234/payment"/>
        13: </order>

In addition to the order-related information (e.g. ordered items, received date/time, etc.), the Restbucks service also includes Atom <link> elements that could help the customer and the service make forward progress in their interaction. The Content-type header of the response would probably be something like "application/vnd.restbucks+xml", indicating to the customer that they should use our Restbucks-specific payload processing rules. It's these rules that define how to process/understand an order's state representation, including the use of the Atom <link> elements.

Now, if you think about it, we do something very similar with the Atom Application Protocol. The returned representations contain Atom <link> elements that have very similar semantics. One could say that the equivalent happens with XHTML, since the returned documents contain links to support the state transitions in our "hypermedia as the engine of application state"-supported application - browsing the web.

We observe that clients receiving the resource representations with embedded links, need to extract those links from the payload and make use of them in order to make forward progress. Each client has to implement the hypermedia-specific behavior.

As with each pattern, we might be able to generalize the approach so that software support - through tooling/frameworks - can be introduced. We could, for example, define a Content-type like "application/state+xml" which would allow us to get the hypermedia-specific state representation of a resource. For the order above, an HTTP GET request with the "Accept" header set to "application/state+xml" would have returned something like this...

         1: <feed xmlns="http://www.w3.org/2005/Atom">
         2:   <link rel="payment" type="application/vnd.restbucks+xml" href="http://restbucks.com/order/1234/payment" />
         3: </feed>

This is effectively a way for a customer to just ask Restbucks "what do you expect me to do next?". However, this is a generic question that is valid in many application integration scenarios. Multiple links may be returned, giving consuming applications options about what they could do. This way, a generic software stack could be implemented to support this type of behavior.

One can take it even further and include an Atom <entry> element for each allowable state transition, rather than just a list of links under the Atom <feed> element. Each <entry> will have its own <link> but would also carry a WADL document with more details about the linked resource.

 

So, what does the community think? Is this just wacky? Would you like to see this explored in a more detailed discussion in one of the chapters of our book? Do you think it can be useful?

 

As we were thinking about the above pattern, it occurred to us that the idea resembled some discussions Jim and I had some time ago with Andrew Harrison from the School of Computer Science, Cardiff University, on conversational state description for the Web. Maybe it's time to resurrect those ideas.

9 responses to “A Hypermedia Framework?”

  1. Surely a generic client framework could retrieve application/vnd.restbucks+xml and then simply issue an XPath looking for “//atom:link”. What additional capability does the application/vnd.state+xml resource provide?

    Regarding the concept of embedding links to represent valid state transitions, isn’t that exactly what hypermedia is all about. I think I am missing your point.

  2. I don’t think an extra request is needed (or wise) to discover hyperlinks. XHTML figured out how to handle this, why not use the same pattern? if you want to add links in media that does not support it, why not use the Link Header?

    I would have no problem in creating a ‘micro-format’ that makes expressing links more standardized for user-agents to deal with.

  3. Also isn’t it likely in any complicated business resource that valid transitions are going to constrained by the details of the particular resource (e.g. small purchases don’t need an order number, large ones do) ?

    This suggests keeping the links inline is the way to go.

  4. You might also want to check out Mark Nottingham’s HTTP “link header” draft.

  5. Thank you all for the feedback.

    Darrel… The idea is that we can also include metadata about each possible transition. For example, we could include a WADL document for what is allowed for the next resource in the state machine. Also, how is a generic client supposed to know how to interpret a vnd.restubcks+xml payload?

    Mike… Yes, I am going to have a look at the link header. In fact, it’s something we had discussed with Jim some time ago. Time to revisit I guess.

    David… indeed, it’s up to the application to decide whether to include links for the next transition.

    .savas.

  6. What Stefan says – see draft-nottingham-http-link-header – of course I’ve no idea how to make this work with JavaScript in a browser.

  7. I was missing your point. I now think I understand. The more I think about the idea I do like the idea, especially for POST links. For PUT, GET DELETE links, I like the context that embedded links provide.

  8. I really like this idea. I don’t know that truly generic clients will ever be possible, so I don’t see that as a consideration. I suppose the headed links could be good, but that almost seems outside of the normal flow, if normal can even be considered an appropriate term in this context.

  9. I think links in the resources is a good idea, as demonstrated by hypermedia. But [link rel=payment href=”…”] does not say what HTTP method to use. But I think putting WADL in atom entries is an overkill: why not simply put the WADL where the link would be, or even simpler, put an XHTML form there? A form is a link with extra information – inputs and method; and WADL can also be interpreted as a bunch of links and forms.

    And on top of that, what about replacing rel=”payment” with sawsdl:modelReference=”http://example.com/categories/payment”? Ehm, can you use URIs in the rel? That would do, even without SAWSDL. (btw, SAWSDL is not at all restricted to use in WSDL)