The Secret to RESTful Services is RESTful Clients

I’m sitting in the airport waiting to head back to Seattle after several great days at RestFest here in Greenville, SC. Many thanks to Mike Amundsen and Benjamin Young for being such gracious hosts. I’m pretty tired at the moment, but I had a couple takeaways that I wanted to get out there – mainly so that if I forget, I have a reference point to return to.

First, there were a few technologies that caught my attention that I want to spend some time going deeper on. Some of them I had heard of but had not yet gotten around to looking at – some were completely new to me. At any rate, in no particular order, here’s a list of stuff to look at in more detail:

  • http://apiary.io – API documentation, testing, mocking
  • JSONt – A JSON template language
  • Siren – Another hypermedia media type for JSON
  • RDF(-a), SPARQL, Semantic Web, Linked Data – This is a pretty gigantic space, and so step 1 here is just understanding what all of the different pieces are. However, given the work I’ve been doing with graph databases, this space feels like a natural evolutionary path forward.

The other big takeaway for me, which is really the thrust of this post, is that we (including myself here) proponents of RESTful (or hypermedia, if you prefer) architecture have spent an unhealthy amount of focus on the server. In fact, I would argue that when most people talk about REST, they are talking about building RESTful services (and as a result, focus on things like URI design). Ironically, by spending too much focus on the server, the hypermedia constraint – which is really the key differentiator for REST IMO – remains abstract and something that dogmatic service developers stick into responses with only a vague idea of how we think a client will/should use those hypermedia controls.

This disconnect between service and clients creates the following kind of interaction that happened during the “lightning talks” at RestFest this year.

  • [me to front-end developer] – “having consumed lots of different APIs, what aspect of an API makes it either a pleasure or a pain to work with”
  • [front-end developer] – “that would have to be API documentation”
  • [presenter (a few talks later] – “we should be providing less documentation…client developers should be able to discover our API by ‘following their nose’”

Ummm, hang on a second….

Sure, that sounds like a great idea..

But that’s not the reality that the front-end developer just told you that she lives in.

So where’s the disconnect?

I believe that the problem is that while we may intellectually understand that REST describes the entire system (and not just the server), we don’t practically understand what this looks like because we generally build only the server applications and then make a bunch of assumptions about how the clients will “call the server.”

What I think we need to do differently is adapt a practice from TDD – that is, start out by building a client first, and then build the server from the outside-in. Building a client first will give us a really clear picture up front on just how usable hypermedia controls are in practice and will hopefully cause us to think more carefully about what controls we use, or where we put those controls (perhaps not everything should be in a header?).

At the moment, I’m testing this approach with RestBugs, and I hope to have something to show in the next week or so. But the big idea is this: I’m going to write my client to consume a series of static [JSON] files and will see how easy it is to drive my entire workflow through those resources. I’ll then use that experience (and the resulting representation design) to drive the design of my server, which will then drive the runtime execution of my client.

“recursion…see recursion”

I don’t know whether this approach will work yet, but I’m optimistic…

Succeed or fail, should be fun.

Your thoughts?

 

About Howard Dierking

I like technology...a lot...
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://devtools.korzh.com/ devtools.korzh

    I like the idea as a beginner!

  • howarddierking

    Based on your example, I think it’s important to clearly understand whether what you’re trying to do is distributed transaction or batching. In the case of batching (e.g. delete this batch of emails), it makes sense as an optimization for the client to be able to send a request to delete multiple emails. There are several ways to accomplish this in HTTP, though the key principle is that the client discover this resource as a result of a *link* – so figure out how the client gets the link before you worry about things like what the URL is named.

    If you’re wanting to do a distributed transaction in RESTful system, the pattern that I’ve seen both in literature and working applications like Neo4j, the server exposes a resource that enables a client to create transaction resources, then post updates to the transaction resource and then commit it/delete it. This is perhaps a bit more complex to implement, but from your description, this isn’t what you’re needing to do.

  • Mukesh Katariya

    Thanks for the links.

    How do we achieve as a single transaction behavior over multiple resources to be created/deleted ?

    Assuming Gmail as a client , if i multiple mail items to be deleted , Do we issue multiple request from the client or bundle it as a single request ?

  • howarddierking

    Does REST put more emphasis on client independent APIs?

    >> I’m not sure exactly what you mean by client-independent APIs, but a RESTful architecture avoids making assumptions about any concrete actor in the system (client or server) beyond their ability to interact via the uniform interface.

    Does REST based client calls make your application more chatty with the server?

    >> Not any more or less than any other architectural style. It really just depends on how you design your system. See http://vimeo.com/20781278 for some really cool examples of how you can optimize interactions in a way that doesn’t break clients/servers.

    On cache invalidation

    >> There are several approaches, but the most common for HTTP-based architectures is to use a combination of cache TTL and conditional requests (using either etags and/or last modified time stamps). This implies that you’re ok with eventual consistency. If you need full consistency, don’t cache. Lots more info on caching at http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html

  • Milo

    Cool idea. It feels this approach would help people in keeping with YAGNI. Trying to guess what people might need is always difficult.

  • Mukesh Katariya

    I am just a beginner with the REST world.
    Does REST puts more emphasis on client independent API’s. ?
    Does REST based client calls make your application more chatty with server ?
    I am still reading but not very clear on how the Intermediary caching style works, with respect to Reading a resources or finding a certian set of resource( Say CustomerResource), If some modify the Resource how does cache gets notified ?

  • SmartFile

    Enjoyed your post! Thanks for sharing :)

  • howarddierking

    That sounds like a cool technique, though I’ve never used Caliburn.Micro, so can’t comment on any of the details. It was really interesting, however, to see the disconnect between client and service developers play out in the RestFest discussions, so it seems clear to me that many still see client development as hard – and service developers should pay attention to this.

  • http://rodolfoferreira.com.br/ Rodolfo Ferreira

    Very interesting..Maybe we could even give up implementing some features that we noticed clients will never need to use, just because we’ve started by building the client. Good point

  • Daniel Marbach

    Hy howard
    Building a client which interacts with a RESTful service isn’t that hard. I usually map the REL to a view or viewmodel. For example with Caliburn.Micro in a Rich Client I can simply have a conductor with child items (when I don’t need lazy loading of VMs) and activate a corresponding VM in the conductor when a certain REL is found in the stream. The navigation links can be directly mapped from the hypermedia to the views links or buttons. Combined with a proper task-based UI and underlying good ressource design of the server API is see no big hurdles here.

    Daniel