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.
So, RESTafarians go in hiding nowadays … they don’t have the courage of their opinions anymore. I think you just proved my point … time to unREST!
A most welcome (and excellent) article.
And for a newcomer your site/articles provide an education :-)
Can you explain a bit more about the comment “forget the 4 little HTTP verbs".
I’m a SOA architect but HTTP is not really my specialist area. I have used JAX-RS to implement REST services using annotations, but I don’t remember anything about creating additional http verbs.
How would you go about doing such a thing? What’s the easiest way to take up your advice?
one of the problems with uniform interfaces is that you can easily implement a new uniform interface on top of an existing one, which leads to a bit of confusion. For example, you can always implement a synchronous call, on top of an asynchronous protocol and vice versa. SOAP, with it’s send/receive uniform interface, is of course layered on top of HTTP’s uniform interface, but not just HTTP, it also has JMS bindings, and so on.
So first you should decouple your uniform interface definition from how it will be implemented.
The idea is not so much to add HTTP verbs since that’s not possible, nor desirable. HTTP’s uniform interface is broken. When you have to use POST in lieu of GET because of URL size constrains, you realize that there is not much uniformity there.
The key is really to define what is meaningful to your domain. For instance in the mobile world, (push) notifications and data synchronization requests (due to intermittent connectivity) are very common across all mobile applications and services. Can HTTP support either? no. If you write a lot of mobile applications, you need to come up with a “uniform” way to achieve these exchange patterns otherwise your APIs will be inconsistent and you will not be able to build some dedicated infrastructure to deal with each type of interaction. You can layer them on top of HTTP, SOAP, JMS, SIP, whatever.
All that I am saying is that different domains may require different uniform interfaces, HTTP’s uniform interface is a pretty poor choice for anything other than browser-to-server interactions.
Is this post a joke? You don’t actually make a single convincing argument against REST. Questions like “does anyone actually do this?” and complaints that HTTP verbs aren’t helpful outside of the web (HTTP is a WEB spec) aren’t arguments against REST but rather make me doubt that you’ve spent much time thinking this through…
For example, you say REST forces us to hand-code things we got for free in previous distributed computing paradigms. Ok, what came before HTTP and REST that gave you these items for free? These things were specified for interaction over the web. To me, building ALL your communication points in HTTP is silly. Once I’m behind my firewall, I can do whatever I like. I don’t design all my services to communicate through REST because there’s no reason to do that but that doesn’t make REST bad.
As long as one is not slavish to this approach, there is certainly a lot of good that can be gained from much of REST and HATEOAS. I do agree that those who take an elitist approach to REST are not helping and I don’t believe developers should lose any sleep over how RESTful their services may or may not be. I strongly disagree with your dismissive attitude regarding REST however and think it’s silly to suggest developers ignore HTTP, REST and HATEOAS and just make it up as they go.
Your assertion that push notifications and data sync being common in mobile yet unsupported in HTTP doesn’t make sense. How is a sync call for a given resource or entity not a GET? And why can’t you batch and send notifications from the server to the client from a GET? The notifications are about something and sound “resourcey” to me. Web sockets seem like a great alternative or even Comet if you can’t get sockets support yet in mobile (I wouldn’t know not being a mobile guy).
Respectful discussion of these patterns is likely to draw those who can provide insight into these things. Most REST proponents aren’t going to respond to a post like this because it just seems like you’re trolling.
>> me doubt that you’ve spent much time thinking this through…
Well, I wrote well over 100 posts on REST and spent thousands of hours on distributed computing specs, so I am not sure this is a fair statement.
Four years ago, it would take me on average 2 minutes to talk to a web service. Today, if I am lucky, this is 2 hours, if not 2 days. I know even someone who spent 2 weeks writing an objective-C client for S3.
So “REST” is a major step backwards. Anyone who disagrees is simply emotionally attached to an idea that simply does not work.
>> those who take an elitist approach to REST are not
>> helping and I don’t believe developers should lose any
>> sleep over how RESTful their services
So, if REST is “do the hell of whatever you want", let’s be clear.
>> How is a sync call for a given resource or entity not a
Alex, you obviously either don’t understand what I am talking about or you are completely ignorant.
How does HTTP work with intermittent connectivity? Does every client on earth has to re-implement it’s on freaking data synch protocol? If I understand you correctly, you are telling us that “hey as long as you can send a message from A to B, you are fine, hence REST (and HTTP) can do everything". This is beyond pathetic.
>> Web sockets seem like a great alternative
Do you understand the cost of a long running HTTP connection in terms of device power consumption? Do you understand the cost of open 20 HTTP connections to serve a single web page on a mobile device?
>> you’re trolling.
It seems that “Trolling” is the new incantation from the RESTafarians when anyone dares asking them to show what is actually RESTful today.
I can only quietly laugh to your “REST can do everything” arguments, the truth is that REST can do nothing. We have now thousands of public “Web APIs” to prove it. Less than 1% are “RESTful".
At this point, I am not quite sure who is … trolling
The blog post seems to be talking about 3 things at the same time:
The application logic (actions done by the software) saying that it can’t be achieved by HTTP (messages exchanges, not actions) and qualifying it as a REST issue, when nothing has really been said about REST in this POST (specifically hypermedia nature of messages).
What is happening on the application layer has nothing to do with HTTP, and that’s the part which is disturbing for most people. There is a difference about exchanging messages that will create actions (HTTP) and exchanging actions (what you seem to be advocating for).
There is a lot of discussions worth reading into
Just for your readership, because I think you already read it.
There was an interesting work from someone, I can’t find the link now, who was evolving REST architectural style in the context of transitioning from Web Documents to Web applications. That would have be cool to have your reading of it.
1. The time it takes to interact with one vendors touted REST API does not invalidate an entire architectural approach. If you want to invalidate REST how about some objective, non-anecdotal reasoning behind why it’s wrong. Not “I don’t like it” or “It was hard".
2. Insisting that anyone who doesn’t hold your point of view is ignorant, over-emotional or not as intelligent as you isn’t an actual argument. You’ve simply revealed your rather high opinion of yourself.
3. I did not say, “REST is do whatever the hell you want". I said that I believe a slavish mindset isn’t productive. I think a little pragmatism is just fine.
4. Nor did I say, “REST can do everything!” I also didn’t say to make 20 connections from your mobile app.
5. Just because you personally don’t like REST or find it an obstacle doesn’t mean “REST can do nothing” or that the pattern holds no value.
6. I said it *seems* like you’re trolling. Also, I’m hardly a “RESTafarian". Make up your mind, first I’m saying it doesn’t mean anything, next I’m a zealot.
You’ve failed to address any of the problems I identified in your original post and instead are inferring obviously flawed arguments in my response that you then easily tare apart because that’s much simpler than addressing my original concerns with your article.
Let me try to make it simple:
1. What is your current solution for sync and notifications over HTTP for mobile applications?
2. Can you objectively define the flaws in REST without the use of anecdote or by enumerating how many people aren’t doing it?
3. Can you define boundaries for when it is/isn’t appropriate to use an HTTP endpoint for services?
4. What were you using before HTTP/REST that was so productive?
If you can answer those questions I think this can become a productive conversation. If not, that’s cool, it’s your blog and at the end of the day, your inability to have an objective conversation about REST only discredits your stance.
let’s take an objective measure. Let’s look at how many Web APIs are truly RESTful on the programmable Web directory? There are 3500 public APIs, not two are the same, it takes hours just to decipher the logic behind each API and I am not even talking about signing requests.
Is that what “REST” brings us? We have now 4 years behind us, lots of data points, we are past the discussion of POST vs GET or PUT. We can see what people do, how they do, and that is not RESTful.
Please show me an example of HATEOAS that works, i.e. the server adds a link and the client adapts without any changes to the new link.
Actions are inherent to information, not programming. This is why so many Web APIs are action oriented, not because don’t get it, because this is the semantic of what they are trying to do. Who in their right mind would spend time to convert an action into a standard verb and a noun. This is completely silly.
Designing truly RESTful APIs is hard.
99% of the existing Web APIs are HTTP APIs, not RESTful APIs. They should just be named accordingly. Don’t blame the 1% for this.
How many hours saved thanks to using standardized status codes? standardized headers? built-in caching mechanisms, standardized compression mechanisms, scalability due to statelessness constraint, etc.?
Reading your paragraph about versioning (and your first point about the browser being the sole target of REST designs), it looks like you don’t understand the merits of media-types.
Regarding your comments:
Your S3 example: you’re talking about an HTTP API that redefined a whole authentication mechanism. That’s probably what took so long to figure out for your (bad) Objective-C programmer.
Also, since you’ve written more than 100 posts on the subject, you should probably know by now that Amazon is not especially renown for the RESTfulness of their APIs.
If you find that interacting with an API that use HTTP as an application protocol is hard, then I can see why you would be lured into thinking that WSDL is the way to go (which version BTW?).
That being said, use whatever makes you happy.
Just don’t rush to conclusions based on your (apparent) limited experience with the style.
Ok, guys, I am not going to do another round what is RESTful and what is not, the mere fact that we still about it proves my point, REST is whatever you want it to be. I have already spent 100 blog posts on it.
Here, I have tried to write a blog post in the “peace” to world state of mind. If you want to be RESTful, you can, the more power to you. If you don’t that’s ok too (what you may not know is that 99% of the world is like you): it is actually cool to be RESTless, just make sure you follow three simple principles.
If you prove me that more than 1% of the Programmable Web “Web APIs” are following Roy’s REST definition, we’ll talk again, otherwise, REST is deeply and totally irrelevant, and frankly a waste of time for everyone.
I am not going to debate REST/SOAP, we are past that. They are both irrelevant in the world of Converged Applications. Like everything things need to “evolve” to “survive".
I’ve argued in the past that S3 is not a good example of a RESTful web service, or even a good example of a good API, period. Moreover, in S3’s own documentation, the example implementations of PHP and C# bindings are completely inconsistent - the client API behavior is totally different in how it treats errors. Someone wrote an open source C# binding, which is equally bad - it is just static methods everywhere.
So what’s your point? What examples do you have beyond S3?
I have at least 3000 examples, just take the Programmable Web Public Web APIs. They are all completely inconsistent.
With 3-legged authentication scenarios, lots of API designers put the developer credentials (API key and shared secret) in the URL path. Some days you just want to cry out loud.
NOBODY does REST, so please leave us alone, get us a contract back, get us versioning back, I can’t read another “Human Readable” API description. I AM SICK OF IT.
When used in the proper context, i.e., one where the state of a resource needs to be transferred, REST is very easy to use and fits like a glove. I do REST and it works great. Most of the people I’ve known who don’t like it don’t really understand it.
What I don’t understand about your article is where you say that REST is meant for browser-to-server use. Sorry, but I’ve never seen a browser to leverage DELETE or PUT. Moreover, if you are exceeding your query character limit in the GET line, you are probably using it wrong.
it would be best to substantiate how and where you use “REST". The typical response of RESTafarians is “you don’t understand". I have heard that for 4 years. Obviously 99% of developers are in the same boat. Maybe you guys should focus on educating people about REST rather than telling the REST of world “you don’t understand".
Ah, because REST is just about DELETE and PUT? and because most browsers have turned off that capability, it means that it was not designed with the browser in mind? … and Wiki’s don’t (semantically) DELETE or PUT “pages” on a server.
Guys, party is over. REST never existed.
“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.”
REST does not define what verbs should be used. It’s HTTP that does that. Defining additional verbs and media types for a particular problem domain is a perfectly valid application of the uniform interface constraint. In the upcoming “SOA with REST” title we clearly identify governance of the uniform contract for a given service inventory as a key responsibility within an overall inventory governance framework for REST-style SOA.
What REST does do is require that any interactions supported by the verbs of the uniform interface also be stateless. That’s a constraint that can rapidly become less important in smaller architectures than that of the Web.
“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.”
Everything gets explicitly versioned, yes, but old implementations should be able to work with new implementations. There is a significant amount of benefit to be had from ensuring both backwards-compatibility and forwards-compatibility. It means less upgrades are required in general, that upgrades are less urgent, and that you get into situations where you have to upgrade the entire world’s systems in one night much less frequently ;)
“A uniform interface is not enough to form a contract, it is only the substrate on which a contract is defined.”
As we discuss in SOA with REST, service contracts are no less relevant in REST than in conventional SOA. However, service contracts are defined in terms of uniform contract methods and media types. The uniform contract focuses on how information is exchanged between services and consumers (the methods) and what kinds of information are exchanged (the media types). It is abstracted away from any specific business context in which you might want to transfer a particular type of information in a particular way. The service completes the semantics of any particular interaction by defining specific URLs for which a specific method will have a specific effect, and for which specific media types are understood.
In REST we try and minimise the amount of service contract information that makes its way into the consumer’s logic. We do this with the objective of reusing the consumer as well as middleware components in conjunction with multiple different services that all support the same uniform interface methods and media types. If a particular consumer only ever wants to talk to one service, that’s fine. It can embed whatever contract information it wants. However, we expect to be able to support generic consumers and middleware that is not locked in to only interacting with a single service.
Thank you all for this discussion. We are certainly at a turning point in REST. From the discussions that followed I noted:
a) There are far fewer people that are afraid to say that REST doesn’t work. 4 years ago that was just me
b) all the hardcore RESTafarians only say “look HTTP is everywhere” so why do you even complain /#!/
c) The RESTafarians explain that the reason why 99% of public Web APIs are not designed following RESTful principles is because developers are “bad", “lazy"…
The fact and the mater is when 99% of Web APIs are not RESTful? The fact that all these APIs use HTTP in inconsistent way from a security or semantics perspective is of course of no concern. How would you call that? a failure?
My conclusion is
a) pick a better uniform interface (specially in the light of mobile 3-legged scenarios which will be the overwhelming # converged apps that will be produced in the coming years) -> HTTP’s uniform interface is abysmal
b) define machine readable contracts that can be versioned explicitly -> they are actually much more human readable anyways
c) forget about “coupling” the exchange of a message to resources, that does not work at all, a message is a message, period. -> Define your message types explicitly as part of your contract.
==> extensibility (of message types) is what makes distributed computing work not REST because it enables “forward versioning".