Sunday, July 10, 2011

So, jdubray at Carnets de bord has thrown down the gauntlet, I guess. He proposes "unREST". What is unREST? It's, umm, not REST. Simply put, it's RPC. Pretty bold proposition, don't you think?

Here's to hoping that unREST sweeps the internet so that the Restafarians can focus on working out the details of trying to apply REST as given rather than cleaning up everyone's misconception that REST is using GET over HTTP for RPC.

Let us put an end to "RESTful" web services and "RESTful" URLs, all things REST doesn't really have much of a say over or a care for. Lets hear it for "unRESTful" web services and "unRESTful" URLs. +1 to that.

J (can I call jdubray J? Hope so...) starts off with:

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.

Actually, no. REST has nothing to do with browsers, but unfortunately, the browser model is so pervasive, and it happens to use hypermedia, that it's a reasonable go-to artifact that can be used to help explain the concepts. A common ground between the theory and practice, especially over the limited bandwidth of things like blogs and forum posts. But, naturally, folks take the example given as law and miss the forest for the trees.

He next cites three of Roy's REST premises, and damns them because "nobody" actually implements these concepts.

Finally, he boils it down that nobody does this because there's not tooling for it. That all of the other RPC mechanisms give us the mechanism of exchange "for free".

SOAP gives us WSDL "for free", CORBA gives us IDL "for free", and Java RMI uses Java classes "for free".

SOAP, CORBA, and RMI are all popular, especially behind the firewalls. On the public internet, eh, not so much.

Why is that? Why are these protocols not pervasive in the wild, cage free, free range internet when they give us all this functionality "for free"?

Because the underlying complexity of these protocols inhibit casual adoption. There are rules to follow. Folks hate rules. Because of their complexity, the universal "we" are effectively forced to use tooling to participate. When you have to rely on the tools to do the work, as a participant you tend to ignore the details on the wire. Let the tools enforce the rules.

Consider Java RMI or Remote EJB. As developers, we would create our Java interfaces, methods, parameters, etc. and publish them far and wide using the built in software. In use, did we ever actually look at the byte stream going back and forth? No. It's an opaque binary blob of unintelligible rubbish. And if there was some conflict or problem in the protocol, it certainly wasn't our problem, it was the toolings problem. We coded to the high level interface, and left the nitty gritty to the tooling.

Just like we do today with TCP packets. We don't care what the bits and bytes and network order and packet buffers and sync handshakes or whatever. Open socket, socket.write(stuff), close socket. Shazam.

SOAP, however, is "just XML". It bares its wire protocol to all. If anything the SOAP stacks over complicate things because they give the false hope that we actually have some control over the wire format, when in truth, we really don't. XML it may be, but what goes over the wire is STILL the tooling's problem.

And that's the rub. When Tooling implementation A interprets the specification one way, and implementation B interprets it another, then it's happy fun time for the poor, powerless end developers that need to make it work.

SOAP has matured greatly over the years, and interoperability is always getting better, but developers are still relying on tooling to do the heavy lifting. For J, that's a good thing. If the REST APIs had tooling to where he could drag and drop the interfaces, we'd likely not be having this discussion.

However, if REST APIs had the tooling to do all that, then there would be effectively no difference from HTTP REST implementations and SOAP implementations. Much of the complexity that's baked in to SOAP is there for a reason. On its surface, SOAP is really (really!) simple. It's an XML header and payload. It's really trivial. All of the specifications go in to details about what's IN the payload, the SOAP envelope itself is straight forward.

(Here's a secret, did you know you could implement a REST system on top of SOAP?? Really, it's true! REST doesn't care about the protocol. Does. Not. Care. It's an architecture.)

J mentions agent-to-server, and when we talk about agent-to-server and both the agents and the server are machines, we talk about Machine-to-Machine, or M2M communications.

REST represents the server architecture, and client expectations. A "well behaved" REST client can be quite complicated to be able to handle and support the flexibility that the server can leverage in order to get value out of REST. But here's the news. A BAD REST client, a client that ignores all of the pre-cepts and guidelines that are part of the contract of the REST server, does NOT invalidate the REST architecture. Just because one side does not play along by the rules, does not mean the design or implementation of the server is wrong.

What is a bad REST client? It's something that make presumptions about everything. Normally, a REST client starts at the beginning of a graph that represents the REST server. The initial entry point. From there, the server lets the client know where it can go, and what it can do, what it should do next. A bad REST client may simply go "yea, yea, yea, I've been here before" and go stomping through the servers endpoints as if they own the place.

That's what many systems do today by hard coding endpoint addresses, and making assumptions about payload, and format, and next steps. That's what we do when we write code. "Open socket, send this, get that, send this other thing, get that other thing, close socket". We code the recipe in to our clients, because "we know the way".

Have you ever gone someplace you've been before, made the right, turned left, went down two streets, and turned in to the driveway to find what you were looking for wasn't there any more? "Wa..wa..wait a second, it was just here!" That's a bad REST client.

Ideally, you would have called ahead (like your wife said you should). Perhaps the phone number changed, and you would have called that number instead. Then you would have asked "Hi, where are you located?", and got the new address. That's what a "good" REST client does. Every. Single. Time. That's a major part of HATEOS, in a nutshell.

We don't do that in normal life, because we "know" that, as a rule, things simply don't change that often. There's no way I'm calling the grocery store every week to check on their hours or make sure they're still in the same shopping center I left them in last week.

And that's why bad REST clients can "get by", and why folks see perhaps less value in REST. Because most people that write systems, write small systems. They write systems that they likely control both the server and client side of the equation. When the server moves, the pain of updating the clients to use the new locations is minor one off integration work.

Because what happens to a bad REST client when the server changes? It breaks. It gets to the parking lot and cries "Oh no, Disneyland burned down!". Then it fills your logs with stack traces all weekend, and nothing gets done.

Folks seem to feel there is some magic in REST clients, that since "REST is all about browsers and humans" that the clients should be some Skynet powered super cyber-being. Hogwash. Just code, people, they're just code.

Code that knows to ask for what it wants, code that knows to ask for directions, code that knows how to parse and process the payload as it sees them. What happens when the code gets stuff it doesn't understand? Why, it breaks! Imagine that.

Just like in real life, with humans. You know what happens when you reorganize a web page and move the BUY NOW button to the other side of the screen? The phone rings. People decry "What have you done?" "Where's the BUY NOW button?" "How do I ...". In other words, the agent breaks. Most people are resilient enough to adapt to the change. Most people.

Proper REST clients are more resilient to change. REST clients are kind of like the Unit Tests of RPC. Unit tests help enable development teams to move quickly because the unit tests can inform the team when something unexpected breaks. With resilient REST clients, the REST server can move forward, quickly, with some confidence that the clients will "keep up". They may not understand the newest features, or additional data elements, but they won't necessarily break on the changes to the old ones. When you can count on the phone not ringing everytime you push a change, you tend to be able to move more quickly in advancing the system. Because we all know how much we hate it when the phone rings. At 3am. On your honeymoon...

If you have an in house server with two in house clients, this kind of resilience is not a value add for you. The cost of implementing a proper REST client may well not pay back any time soon, it's simply cheaper to implement, keep track of, and fix bad clients.

But recall, a bad client doesn't invalidate REST. A bad client works just fine with a solid REST server, at least for some length of time.

With cooperative clients, if the server maintains some backward compatibility, then it offers more time for the clients to be recoded/retrained to take advantage of the new features. With cooperative/compliant clients, clients that actually use the information given to them rather than just making stuff up as they go, the server has more flexibility in the changes that it can make without the phone ringing. That's why the server controls the URL space, and the clients don't. It's not their URLs, it's the server URLs.

Giving the clients control over the URLs is like giving the clients control over what office you work in. "Yea, I'd like to move to the office with the window over the beach volleyball court, but, 8 months ago I told UPS what office I was in -- so I guess I'm stuck here."

L O L you say. Absurd you say. But that's what happens when you give the power of the location of your services over to your clients. No beach volleyball for you. Ensure that your clients can look stuff up, and this isn't a problem. Forget UPS, they can call me. Now I just need a set of binoculars.

This is also why the use of ubiquitous media types are important. It's the same process. The media types in a REST system DO NOT carry semantics. The media type is rules about parsing and locating information within the media type. GIF is a media type. Blurry cell phone photos of scantily clad volleyball players is semantics (it means I have a better office that you do). The server defines what goes in to the media type, in terms of actual, interesting data and the application defines the semantics. Using ubiquitous media types means that there is a good chance other systems will ALREADY KNOW how to process it. "That's good, one less thing." -- F. Gump.

In Healthcare IT, there is solid movement behind representing clincial information. One of those efforts is the Clinical Document Architecture, which is based on the HL7 v3 RIM model. There's enough documentation to represent these documents to make a nice, home leaf and flower press. But once understood, and once wide spread, implementors and architects will all be able to leverage and utilize all the work being done classifying disease, medications, procedures and preserving daisies and poppies to enable the flexibility that the ubiquity of the data formats bring. Much like we say today "do you have a fax machine" or "do you have email", we'll be able to say "do you understand a CDA C32" and send a great amount of interesting information. "For free."

Why isn't XML or JSON a "valid" REST format? Even though everyone and their sisters cell phone can process it? Same reason XML isn't an Health IT format. Because REST wants hypermedia formats, not just fancy CSV. It wants something more. HTML is a hypermedia format, XHTML is one that just so happens to be XML as well. So is Atom. XML and JSON, "in the raw", are not. They're just fancy CSV. Others are trying to build better, REST happy hypermedia formats on top of XML and JSON.

Once you get the media type out of the way, you can dwell on the details of the content that are important for the transaction. And from this you can train your systems to work with the interesting data that really matters.

That's why REST promotes using standard formats. So we don't have to learn Yet One More thing. Let's create tools around the existing specifications rather than recreating them, and retooling, and re-documenting, and re-training EVERYONE (and every thing) to use the new ones.

There's this notion, again, that M2M clients are some kind of super powered, semantic inferring, cognitive creation. The whole "out of band information" issue.

Humans (mostly) have this power, but this isn't what REST is talking about. This inference and deduction process of figuring stuff out on the fly. Consider a web site. Arguably the most RESTy thing we have today. Common formats, hyper media, caching, the whole kit.

But, see, this web site is in Japanese. Know what? I can't understand Japanese. At all. Such a website would be total, utter gibberish to me. Does that make it not REST? Hardly.

What about a DNA sequencing system. Do you know anything about the process of DNA sequencing? I don't know anything about DNA sequencing. Even in english I wouldn't know what such a system did, what I would do with it, or why I would do something with it. Does that make the system not REST? Hardly again.

Gonna need some training here. Probably a Phd would help as well. REST doesn't fix this issue. This may be a revelation to some. Amazing, I know.

So get this notion about REST being only for web sites. It's not. It's an architecture for system using coarser data than we perhaps like, capable of being more fluid that we'd like to code for, using data formats we might rather not use. REST tooling is ubiquitous but at the same time, still more in the hand tool stage than the megabytes of frameworks and code generators out there. More integration would be better.

But the true thing that's missing from REST development is the habits and experience of using it. Getting some solid good REST clients out in the wild with a code set amiable to re-use and building of other REST clients. Most folks don't get that far. Software is about abstractions, and REST systems present some very nice ones. But habitually, right now, it's simply easier to write bad clients against harsh servers and deal with the realities of not choosing the more flexible path. For most folks, the value that REST provides is simply unnecessary.

All of the issues and problems that existed with RPC then, before REST was all written down, is still wrong with it today. So, unREST away, please. With your RPC and HTTP tunnels and XML payloads honed to the keenest edge, but do it over there please.

Can I create an unREST tag on SO now?