Since 2007, the industry was told by a handful of people that the "Web" could teach us everything about distributed computing, and that everything we had done before was simply wrong. Four years later, we can only see that the emperor is completely naked (what else could we expect?).
REST was designed with an end-user in mind, operating a user agent: the browser (I know Roy is going to get mad if he reads this). Everything that has been written to apply REST principles to a software agent-to-server scenario is simply wrong. To quote Roy himself:
A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API).
A REST API should never have “typed” resources that are significant to the client. ... The only types that are significant to a client are the current representation’s media type and standardized relation names.
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace.
How many Web APIs are actually designed that way? It is time to move on from all this mind bending serendipitous complexity that brings absolutely nothing, except more lost productivity by forcing to everyone to hand code everything we got for free in previous distributed computing paradigms.
So I encourage everyone to unREST with pride. No offense to Roy, REST is brilliant. It is just not applicable to the problem at hand and we should give him some REST in return, for all that he has given to us. It's cool to be RESTless. Let's not waste any more time.
So what does it mean to unREST?
a) Define a uniform interface that suits your domain
There are many uniform interfaces to choose from: Send/Receive is one, GET/PUT/POST/DELETE is the "REST" one, CRUD has been used for 30 years world widely, ...
Don't be shy, forget the 4 little HTTP verbs, you can even define your own: Query/Do/Notify/Synchronize is a perfectly good one. It means that all methods in your Web API will be of type query, action, notification or sync request.
One could even imagine a 3-legged uniform interface, well suited to support modern converged / composite applications.
In fact, REST's so-called "uniform interface" is quite broken outside of the Web as some queries must be implemented with a POST and lots of people struggle to use PUT, POST and DELETE meaningfully. I have seen a standard using DELETE to implement the "cancel" payment operation. (I bet that's what some would like to do with their CDS transactions... )
A uniform interface is essential to a healthy API, pick one that fits your domain and stick to it. Let your infrastructure know about it from a security , scalability ... perspective.
b) Specify messages
when two agents communicate, they exchange messages. Duh? These messages rely on a shared understanding of some sort be it a standard type or semantic. Define your API messages loud an clear. This is a major step in becoming unREST. The syntax of your message doesn't matter, who cares about XML, JSON, Protocol Buffers? What is essential is that your syntax must be extensible. This is what allows forward versioning.
Explicit message definitions which can be explicitely versioned is essential to a healthy API definition. Message Extensibility is the property that makes distributed computing work.
c) Specify contracts with a clear versioning strategy
There has been many "IDLs" defined over the years, few were truly message based. Think of a relationship between software agents as forming a machine readable "Contract" that defines the rules upon which messages are exchanged between them. A contract is something you break only when you have no other choice. A Contract is most often bi-directional and asynchronous (anyone is receiving any notification on their phone?). Thinking of every relationship as being synchronous and of type client/server, is pure nonsense. Convincing people that they could do without a contract, just with some "human readable documentation" (HRD) is also pure nonsense. How many millions of hours have been wasted worldwide the day we decided to drop WSDL for "HRDs". A uniform interface is not enough to form a contract, it is only the substrate on which a contract is defined. That contract is not uniform, by any stretch of imagination.
Machine readable contracts are the foundation on which to build a healthy ecosystem of Web API consumers. Versioning is essential to evolution and reuse, and hence a healthy API.
Please note that, reuse, in distributed computing, happens the other way around when compared to traditional software engineering. It is the old "clients" of a Web API that "reuse" the new versions of a service (without breaking). Who would expect that anyone could design an API that 3 years down the line would be "reusable" by any 3rd party consumer? It is far more valuable to enable existing client to "reuse" the new features of your API, at their pace, without breaking them, for every tweak you make into your message formats.
That's it, that's all you need to create a successful API nothing else, nothing more. Sure, it would be great if we converge on a handful of uniform interfaces and versionable message /contract specifications. I am not sure we can find "the one" that works for everyone.
I have participated in crafting web-based protocols for most of the last 12 years, starting with ebXML in 1999. The big difference between today and then, is that we have thousands of openly available data points teaching us, we, the "standard" guys, how people actually create APIs, for what purpose. Maybe for once, they could teach us a thing or two. That would avoid picking just a couple of use cases convenient to a vendor's product and forcing the REST of the world fit under that petty umbrella.
You are now free to unREST and laugh quietly at anyone who asks you to marvel at an HTTP header, a "link", use a 7 letter acronym, or tells you with the authority of a story teller that you don't get it. REST was just a (bad) dream, unREST is what you want to do.