Convenience Over Correctness
July 1st, 2008 | Published in column, integration, messaging, REST, RPC | 38 Comments | Bookmark on Pinboard.in
My latest Internet Computing column, “Convenience Over Correctness,” (PDF) is now available. It continues the exploration of problems with RPC-oriented distributed programming approaches that I’ve been writing about in each of my three prior columns this year, as well as in columns from years gone by and in the erlang-questions mailing list.
For years we’ve known RPC and its descendants to be fundamentally flawed, yet many still willingly use the approach. Why? I believe the reason is simply convenience. Regardless of RPC’s well-understood problems, many developers continue to go down the RPC-oriented path because it conveniently fits the abstractions of the popular general-purpose programming languages they limit themselves to using. Making a function or method call to a remote or distributed function, object, or service appear just like any other function or method call allows such developers to stay within the comfortable confines of their language. Those who choose this approach essentially decide that developer convenience and comfort is more important than dealing with hard distribution issues like latency, concurrency, reliability, scalability, and partial failure.
Is this convenience for the developer the right thing to focus on? I really, really don’t think it is. There are ways of developing robust distributed applications that don’t require code-generation toolkits, piles of special code annotations, or brittle enterprisey frameworks. Perhaps the wonderful programming language renaissance we’re currently experiencing will help us to finally see the light and put tired old broken abstractions like RPC permanently out to pasture.
July 2nd, 2008 at 4:24 am (#)
As a CORBA/C++ developer in the “good” old days, a currently SOAP/WS implementer forced to work with some of the supposedly high performance GRID toolkits, but a REST/Erlang/Lisp/.. developer and promoter in spare time, I want to say a big “Thank you, Steve!” for your insightful articles.
Best regards, Stelios
July 2nd, 2008 at 10:10 am (#)
I sympathize with Vinoski’s war on RPC, but he’s overdoing it. Asynchronous messaging either exist in a chosen RPC system, or one can use any old message queue software. Interface coupling is bad, but 1, it ain’t mandatory. One is free to use any sort of blob (binary, XML, JSON, whatever) if deemed necessary. 2. there are tools and strategies to do versioning (and let’s face it, interface versioning is *the* reason we want loose coupling). 3. flexibility bought by dropping tightly coupled interface is paid on the de-marshalling side side (it’s done “manually”). He also seems to be wanting RPC within confines of one language: he speaks about how e.g. IDL fits language 1, but then not language 2. But interoperability is hard. Trying to fit all people into one language is crap and no-one would put up with that either. In that sense, some abstract format is necessary, be it IDL or XML or whatever. And that will bring it’s own idioms (even language-neutral), that won’t fit into language X. He should just let off a bit. He doesn’t know trade-offs for avery particular situation. This way he comes across like paid evangelist. That ain’t right.
July 2nd, 2008 at 10:47 am (#)
@web design: interesting comments. I always like to get reader feedback, but I also like to respond to it if I don’t necessarily agree with it. Let’s go through your comments.
Interface coupling refers not only to data, but more importantly especially in the RPC case to the operation/function/method coupling. RPC makes that aspect of coupling just about as bad as it can be.
Yes, but few are any good. Many brush off versioning criticisms with statements like yours implying that it’s easy, but it’s not.
No, this is definitely false. In RESTful HTTP, for example, there’s no tightly-coupling interface definition language, yet demarshaling need not be manual. There’s a MIME type for the incoming data, and if you’re using a language or library that understands that MIME type, it can make the data available to your application in a suitable fashion.
Actually, I don’t want RPC at all, as surely the column makes very clear! Distributed systems can be easier to tackle in certain languages, and for deployments where such languages make sense, I encourage you to use those languages. Either way, I encourage developers to think about the correctness of the distributed system first, rather than pretending it’s just a language extension, or worse, ignoring it altogether.
Certainly, which is why my column never advocates that.
Yes, that too is correct, and nowhere do I say or imply otherwise. But given that IDLs pretty much force you into a certain type system, even if you tunnel strings or binaries through them as you suggest in your comment, I’d prefer to stay away from IDLs entirely and choose data types independently of the protocol used to send them between applications. You might consider reading my RESTful data coupling column to help clarify this topic.
Nobody can know the trade-offs for all situations, obviously, but I’ve been around long enough to have seen and worked on many different scenarios. That’s precisely why I know that many have their distributed system implementation approach dictated as an afterthought entirely by their choice of programming language.
“Letting off” would be wrong. My goal is to use my hard-won design and implementation experiences gained over many years to try to get readers to see the issues from angles they might not otherwise consider. An article that says, “Yes, we know RPC has lots of technical problems, but you should use it anyway” would be a very little value.
And for the record, I don’t get paid a single penny to write my column.
July 2nd, 2008 at 11:07 am (#)
Hi Steve,
I would be very interested to hear you opinion about the fact that many (if not most) of the examples in the “Programming Erlang” book (by Joe Armstrong) use RPC abstractions on top of “pure” Erlang message passing.
For example, chapter 16, which discusses the OTP gen_server, extensively uses RPC techniques to make the services provided by servers look like local function calls to clients. The “Server 1? code in section 16.1 even has a function called “rpc” which is used on the client side to send the request and do a blocking wait for the reply.
Do you think these are bad examples? Do you think we should avoid using Erlang in this way? Do you think we should avoid using gen_server for this reason?
July 2nd, 2008 at 11:53 am (#)
@Cayle, I believe the difference is that in Erlang, every message looks like it’s sent to another process that could sit on another node (which is, in fact, the case). Even “local” communication is treated this way. So I believe the RPC paradigm as presented in the Erlang book is more of a request/response conversation pattern. Instead of “procedure calls” that can be “remote”, Erlang does “messaging” that can be “local” :-)
July 2nd, 2008 at 12:33 pm (#)
I really, really do think you’re full of shit. The predominance of bad implementations does not itself make the technique bad.
July 2nd, 2008 at 1:39 pm (#)
@Cayle: what Stefan says is correct, but it’s also important to note that the syntax and mechanisms by which you send messages in Erlang are completely different than those used to call functions.
The Erlang
rpc
module, which I would argue is misnamed, is just a layer over the underlying Erlang distribution mechanisms, giving you common blocking, non-blocking, and multicall patterns. I have never had reason to use that module, but I know it’s there should I ever need it.Another thing to keep in mind about Erlang is the linking mechanism, which I was just talking to Joe Armstrong and Klacke Wikström (who wrote
gen_server
, among other things) about last weekend. If you are communicating with another Erlang process, you should have either usedspawn_link
to start it if you’re the one who starts it (perhaps Joe’s example you cite should usespawn_link
instead ofspawn
, but I don’t think it matters there because his intent there is to lead you through the thought process used to derive thegen_server
in the first place), or usemonitor/2
to track it if you’re not the one who starts it. With this in place, you’ll quickly learn of any problems with the receiving end and be able to take corrective action. Erlang supervision trees are a critical part of creating reliable distributed systems.So no, I would not avoid using
gen_server
. It works extremely well for allowing clean IPC without ignoring network effects or being unable to do anything about them.July 2nd, 2008 at 1:50 pm (#)
@Mark: have you ever read RFC 707, where RPC first came from? The RFC itself outlines problems with RPC and even includes warnings about using it. Go read it, and pay special attention to section 4c1. Suggesting that it’s all just an implementation issue is missing the point, and merely proves my assertion that many developers just blindly choose the convenience while ignoring the very real problems associated with the RPC abstraction.
July 2nd, 2008 at 6:23 pm (#)
I agree with Steve. I don’t believe he’s overdoing it when he criticises RPC. Too many people still don’t get why RPC is bad *in a SOA context*. Mark Little makes the point that RPC works for a lot of people and he’s right, but when we talk about SOA and abstract concepts like interface coupling, most people’s eyes tend to glaze over.
I’ve tried to understand the core characteristic of SOA by approaching it from a number of different angles. Finally, I’ve settled on one model, which I call the Viewpoint Flip. Most paradigms (especially OO) focus on a Domain’s view of itself. It’s an inward-looking view. But SOA is an outside-in view. It’s how service consumers look at a domain. If we merely expose methods on objects through a remoting mechanism, which is what RPC (or RMI in the OO case) is, then we’re making a semantic error. We haven’t turned the viewpoint from an inward one to an outside-in angle.
The moment we do that, we simultaneously achieve SOA-style decoupling and get rid of RPC, because we’re dealing with entirely new verbs that are only loosely coupled to existing methods on domain objects.
REST achieves this Viewpoint Flip automatically, because GET, PUT, POST and DELETE reflect outside-in thinking. They’re what service consumers do to resources.
SOAP (using a messaging style instead of RPC) is *capable* of achieving a similar Viewpoint Flip, but only if the designer sits down and explicitly designs a set of outside-in verbs that form service operations. Hardly anyone does that, so we often end up with RPC *thinking* even with SOAP messaging. All the doc/lit styles in the world don’t save us from RPC. Only the Viewpoint Flip does.
I’ve blogged about it here.
Regards,
Ganesh
July 2nd, 2008 at 6:33 pm (#)
It’s a question of value systems.
Developers build things that conform to their value system (i.e. laziness, impatience, and hubris , which I say partly with tongue-in-cheek).
Systems architects (of the “Rechtin and Maier” variety) build things that are structured to fit the heuristics & styles they know will enable desirable properties in the system.
July 2nd, 2008 at 6:41 pm (#)
@Ganesh: I think that’s an interesting and useful way to look at it. Reminds me of Alan Cooper’s The Inmates Are Running the Asylum, which points out that many developers are poor at developing user-facing interfaces because they think the customer/user is just like them, with the same in-depth knowledge of the problem domain, and that’s very often not true. Cooper thus encourages thinking about such interfaces from the customer viewpoint — overall it’s an excellent read. Your Viewpoint Flip is similar in the sense that it encourages the developer to consider the system from the customer perspective, outside-in as you say.
July 2nd, 2008 at 11:27 pm (#)
Hi Steve,
One thing that I’d like you to explain is how the HTTP REST and Queue approach gets around the problem of Impedance Mismatch? Queue systems and HTTP will move the message around for you in a way that offers more flexible solutions. I agree completely here. But these systems ignore the issue of the type system completely and put the impedance mismatch problem back in the hands of the developer. Sure you can then use XML or JSON or something else in the message, but the developer has to do some harder work getting the content into a form they can use.
Also, I notice that you’re completely enamoured with the Erlang approach. Having not studied Erlang, I’m interested to know what its presentation layer looks like. Does it require both client/server to be written in Erlang, or is its data format a separate system? ie How does it deal with the Impedance Mismatch problem?
My personal take on many of these RPC systems is that they gave a black box that tried to do everything from end to end. As you said, it tried to make everything look like a nail. However, I don’t think it means that what was inside the black box wasn’t actually good.
This actually brings up another point about Erlang. Your “Pid ! Message” example looks like another black box. Have you given up one black box paradigm for another? Sure it is simpler, but looks like a black box all the same.
I’m not in favour of RPC systems, but I am in favour of breaking those RPC systems up into useable pieces. A lot of smart people built these RPC systems; its seems you’re saying it was all rubbish and it should all be thrown out.
Thanks for another great article, David.
July 3rd, 2008 at 12:55 am (#)
@David: reasonable questions, let’s go through them:
It comes down to flexibility. RPC-oriented systems include their own type systems, and since the overall goal of the system is to be mapped into the language so that using it is just like using any other code in that language, that type system better map to the language’s type system pretty well, otherwise you get the impedance mismatch. And no matter what, you only get that one type system. As a result, many RPC packages claim to be language-independent but they really map well to only a small set of languages, typically popular general-purpose imperative languages. Neither REST nor MQ, however, make any pretenses about trying to be mapped into programming languages such that using them looks just like any other code in that language. MQ doesn’t really force any type system. REST relies on media types, and since it imposes no language restrictions, different languages can map those media types as they see fit. Furthermore, RESTful resources can and often do offer multiple representations, thus allowing clients to choose the representation or media type they like best. The difference in flexibility between RPC approaches and the others is quite large.
In an Erlang-to-Erlang scenario you’d pass Erlang terms from one process to another (where “process” refers to an Erlang process, not an OS process). But to communicate with other non-Erlang systems, you have to operate in terms of whatever data they deal with. I’ve done quite a bit of integration between Erlang and non-Erlang systems, and it’s pretty straightforward. Check out the way Erlang can parse network messages using its bit syntax — incredibly powerful.
By “black box” I assume you mean a construct that hides the network and its effects. If so, then no, it’s not the same. That construct does one thing: a non-blocking message send. Erlang’s process linking and monitoring, as I explained in another comment above, operates behind the scenes to keep things that talk to each other aware of failures so they can take corrective action.
This question comes up often, and thanks to Ulf Wiger and a few others on the erlang-questions mailing list, and also thanks to Martin Fowler, here’s the way I now answer it:
“When the facts change, I change my mind. What do you do, sir?”
—John Maynard Keynes
July 3rd, 2008 at 1:25 am (#)
@Mark : Before saying idiotic things, THINK about it. Or at the very least don’t show off your name and homepage like a true idiot. Hide yourself like me! :)
@Ganesh : First off, the fact that you have a blog titled wisdom of Ganesh itself tells me I should ignore your comments in totality (as it shows how hung up you are on yourself, esp. the banner on your blog). But anyways, as you are on Steve’s Blog who I immensely respect
…
what you are talking about is pretty old and is explained without using corporate speak by Steve Jones
(http://service-architecture.blogspot.com/2008/03/soa-mentality-its-about-you-not-me.html)
(funny how the steves seem to rule nowadays). No need to use big fancy terms … you need a major speakpoint-flip there ..
GET/PUT/POST/DELETE is what consumers DO to resources!?!? What are you
talking about ?
GET doesn’t do ANYTHING. It is just for kids to check out the stuff.
PUT / DELETE are the ones that do something to the resource.
And pray what does POST do to the resource? Ohh no one knows that!
The main idea of REST is the server telling the client what it can / can’t do to a resource and what that implies. clients MUST NOT assume stuff based upon the names of the verbs and the URIs (other than the basic assumptions given by the uniform interface like idempotency).
Thats what gives you loose coupling. The fact that PUT/DELETE can be used and cached is great , but the best you could do with that is (fielding’s words) “file-storage”. The whole point of REST is the server telling the client what it can and can’t do. The client doesn’t magically say “Ohh! I can do a PUT here.. cos thats the name of the resouce , so if I do a PUT at the book resource it will make a new book for me! WTF?!?” . So that outside-in thinking that you are talking about is bollocks …
your next lines are even funnier. SOAP is nothing but an envelope. What you have essentially stated is that “if you put the right things in an envelope , you can do right things with it” .. yeah thanks for the insight on that one. And again you come back to your stupid corporate speak “Viewpoint flip”.. did your bank bosses pay you for coming up with this cool new term or something ?
@Steve : Awesome column. A small questions : What do you mean by fan-in and fan-out scenarios ? I have never heard of someone talking about fan-in / fan-out before …
I think the problem is that till not too far back , the concept of “Web-Scale” was missing from most of the literature on distributed systems (and mindspaces of people working on them , remember yourself writing all those RPC books ? ) . I think I remember seeing this in Tanenbaum’s book : “Distributed OS is something which is over a network but doesn’t let the user know that a network exists” (or words to that effect). What can you expect after such words? Its only now that people have woken up to the need for Web Scale products.
RPC wasn’t a mistake. I always get pissed off with people calling something that worked in the past a “mistake”. If it worked it was a success , that is the biggest decider of right/wrong. Nothing else. Thats like those bloody python/ruby programmers looking down upon PHP programmers. Well guess what ? most of the biggest sites in the world are written in php and they work and kick ass. Thats what decides whether it was right or wrong.
With RPC , at the use case scenarios and the scale at which people were using it , this hiding of the Network was a not-that-bad an abstraction as it at least got things done. You didn’t have to retrain your programmers and you got an application out. DONT UNDERESTIMATE the importance of this. Now you want an application on the webscale (or more scalable application whatever) … you need to retrain your programmers. But that doesn’t mean that RPC was a huge mistake. It helped keep your IT systems up and running all these years.
Trying to work with what you used for your intranet on the web-scale is a mistake as then the not-too-bad abstraction becomes one major huge screw up..
July 3rd, 2008 at 1:27 am (#)
@anonymous: regarding whether RPC is or was a mistake or not, the way I look at it is similar to developments over the centuries in physics, astronomy, etc. For example, we used to think the Sun and other planets revolved around the Earth, and a lot of bright people who firmly believed that put a lot of time and effort into tracking the movements of those bodies, developing theories and equations that explained their movements and relationships, etc. By doing so they no doubt helped advance astronomy and physics and got us closer to the right answer. But despite their noble efforts, they were wrong — their work was full of mistakes, and nobody can pretend otherwise. Likewise, I agree that RPC taught us a lot along the way, but to pretend it’s not broken just because we once found it helpful is disingenuous IMO.
July 3rd, 2008 at 1:29 am (#)
““When the facts change, I change my mind. What do you do, sir?”
—John Maynard Keynes”
awesome quote! :)
But as Mark Baker (I think it was him) said
” should these people who pulled out so many lies over the year be even allowed to speak”
(referring to Sanjeeva Weerawarana (original WS-* lover) when he suddenly flipped over and started his affair with REST )
:P
I am not saying you shouldn’t talk .. but I am just hoping that you learn humility and a sense of humour about yourself :)
And I will be sad if you block my nice long previous comment …
July 3rd, 2008 at 1:40 am (#)
@anonymous: Mark Baker didn’t say that, Ryan Tomayko did. And what he specifically said is that people who used to push that stuff should have to resign, which is precisely what I did! I left that post a year and a half ago.
One of the reasons I left was that I had sat in a meeting with a very important customer who was having all kinds of interface-related coupling problems that were resulting in lots of major development costs, and I couldn’t suggest to them that REST could solve that issue without blowing a major $$$ deal. I’ve never lied under such circumstances, but by having to remain silent, I felt like I had. After that, when I couldn’t get the company to consider incorporating REST into the product set (nor could I get them to use Erlang and save themselves some serious development coin by doing so), I resigned.
July 3rd, 2008 at 4:15 am (#)
No!! You can’t compare these developments to developments in physics/astronomy etc. ( you have done that in previous columns with your “precopernican astronomers with their convolutated equations for the earth-centric theory” I loved that!) … this is systems development. There is no INTELLIGENT DESIGN/The Ultimate Theory here. It is all evolution (this I am SURE was linus trovalds , but it isn’t my day today ….) Every tiny step in the evolution is equally important and equally usefull. Maybe some step was done not because it was the best step but because it was the feasible step. That still doesn’t loose it of its importance.
In human evolution (we seem to be in analogies today!) , EVERY step is/was important. Having weird powerful ape-like hands was useful when our main aim was jumping from trees to save our asses but now the nimble artisan hands are much more useful. times change , requirements change . We do what we gotta do to get through it.
Screw it , I am not able to keep up with the analogy now!
REST is ann architectural style, one of many. It achieves some particular properties that are especially desirable for LARGE scale distributed systems. The point I was making was that in /*small* scale distributed systems, RPC is acceptable as an architectural style Do you disagree with that? (I think thats what you are saying .. but your only argument seems to be that RPC is fundamentally broken cause it hides away the network, which I don’t think is that much of an issue in small systems. Are you saying that even for small systems RPC is fundamentally broken? Cos I have programmed with Message Passing (MPI) in small clusters and I would rather do RPC )
While writing the comment , it was Mark Baker vs. Tomayko in my mind… remembering the whole article now, I realise .. Mark could have never written something so funny.:)
July 3rd, 2008 at 10:05 am (#)
@anonymous: IMO hiding the network is a concern regardless of its size. It’s like the guy who uses a fixed-size array of size N in his code because he thinks “nobody will ever pass more than N items to my application,” which of course blows up a few days later. It’s easy to fix that issue, but it’s hard to fix the choice of RPC. I believe many choose RPC only because they choose their programming language first and don’t think through the distribution aspects much, if at all. If they were to instead consider the distribution aspects first and choose a language that best suits the problem, they’d be far better off, regardless of the size of the network.
July 3rd, 2008 at 1:51 pm (#)
“Every tiny step in the evolution is equally important and equally usefull. Maybe some step was done not because it was the best step but because it was the feasible step.”
I hate to attack your analogy, but that’s not how evolution works. It’s like a gnarly bush rather than a tree. There’s no purposeful trunk striving towards perfection, there’s a billion dead ends going off in every direction, and a bunch of branches with many utterly useless, illogical, or simply less efficient featuresets – I mean mutations – that sometimes survive as long as any of the others due to other factors, all within a constantly changing environment that sometimes brutally targets and kills off new mutations that could have been crucial for survival in a different (earlier or later) time.
The idea that evolution has always been striving towards the present and will continue along a vector towards some hyper-present in the limit is an idea that comes from thinking of things after the fact.
The purpose of my rambling? It’s alright to say that it would probably have been better off if some things had never happened. It’s not always true to say that some aspect that existed before along an evolutionary line had to be gone through to reach where we are today. That very aspect may have been suppressing or preventing what we have today, and it had to die of its own crufty bloated weight before we could get to what we have now.
This doesn’t necessarily describe the RPC/REST relationship…
…no, it totally does :-)
sorry for being snarky
July 3rd, 2008 at 4:43 pm (#)
aah I know .. thats why I stopped using my analogy half-way. What I was going to say next was “Every step is important even if its only point was to show us what not to do! ” then I realised it actually goes against my argument and helps Steve’s argument, so I shut up , hoping no one would notice :)
But YOU had to come in :)
so I renounce my analogy as it now helps you and not me :P
July 3rd, 2008 at 8:58 pm (#)
Hi again and thanks for the reply to my questions. There seems to be a sub-text to what you’re saying about RPC. Hopefully you can elaborate, but the sub-text I’m reading is:
One of the fundamental raison-detre’s for Corba and WS-* was to create a interoperable world of systems and languages working seamlessly together. It sounds like you’re saying that this goal isn’t achievable. As its not achievable we should accept that change is inevitable and that we should use the best product for the job at the time.
When you suggest erlang to erlang communications you are in effect suggesting that we should build closed systems that you a single language. This obviously has the benefits that we don’t need to worry about the impedance mismatch because the data presentation used matches perfectly the language structures.
Although that brings another question. If you’re operating in an erlang to erlang environment then how do you specify and ensure the data contracts? Do you accept that if you need to change a message structure that you go and upgrade all your systems? The whole question of data constracts and versioning is ignored by MQ systems. Is this another area where you accept that this shouldn’t be handled by libraries, but instead be handled by external people and processes?
Now bringing this out to the bigger ugglier world of interoperability, I’m really surprised to here you suggest bit syntax! Are you suggesting that when non-erlang communications is required that you go back to programmer rolled bit syntax? This would suggest putting the data contracts back into documentation.
Sorry, this is bringing out more questions than anything else. I guess the crux of what I’m trying to find out is in these closed systems (eg erlang-erlang, or XYZ data on MQ), how do you manage the data contracts and versioning of data structures? Then secondly, if you do need interoperability with external systems is the only two options; 1. Bit syntax with good documentation. 2. XML Schema with all the joys of XML. 3. Something else?
Have we really moved into the post modern deconstructionalist era? :)
July 4th, 2008 at 12:06 am (#)
where did you get that he is advocating erlang-erlang communication?
he is saying that the fact that you are using the network shouldn’t be hidden from the programmer , he shouldn’t live in a magical world of Local/Remote Transperancy. And he gives an example in Erlang.
There isn’t any reason why it can’t be interoperable. Thats the whole point of REST. UNIFORM INTERFACE!!!! how more interoperable can you get ?
You really don’t get REST, do you? Maybe this will help
http://netzooid.com/blog/2008/02/07/why-a-restful-idl-is-an-oxymoron-and-what-we-really-need-instead/
In CORBA/WS-* , the KEY was the IDL or the name of the method .. in REST the KEY is the mime-type.
July 4th, 2008 at 12:37 am (#)
@David: I’ll quote each part of your comment again to keep my responses clear.
CORBA was about objects: bringing OO to distribution. That was the original goal. I think the multi-language aspect of it crept in almost accidentally, due to the initial OMG members realizing they used a variety of implementation languages and thus requiring that each of their languages be supported. WS-* was, umm, well I don’t really know anymore what WS-* was, other than a huge mistake.
However, I am definitely not saying the goal you describe isn’t achievable. After all, the web does precisely that! Lots of web servers, web clients, and web applications written in a very wide variety of languages, all interoperating pretty seamlessly and correctly. It works because HTTP is RESTful and REST isn’t about trying to extend general-purpose programming language models to distributed systems, but is instead specifically and directly about distributed systems.
I think either I’m not making myself clear, or you’re not understanding me, or both. Nowhere am I suggesting single-language systems or closed systems are the answer. Rather, I’m saying that approaches like REST that focus on distribution and network effects are far better for heterogeneity and integration than systems that focus on languages and trying to extend them to transparently cover distribution.
Umm, in Erlang?
You asked how to deal with non-Erlang systems. I assume some of those systems will use binary protocols. If so, then Erlang bit syntax makes parsing and constructing messages in such protocols way easier than anything I’ve ever seen before.
As for general data contracts, RESTful systems use media types, or MIME types, for that purpose, as they are globally-agreed data formats. They’re registered with the IANA, and that’s where they’re documented. Different languages have different ways of handling different MIME types. In Erlang, you can handle pretty much every such type with binaries if you want to (you’ll need to know some Erlang to understand what a binary is), and binaries also enable use of the bit syntax where appropriate. But all in all, you might want to go back and read my recent “Demystifying RESTful Data Coupling” column (PDF) for more answers.
I think the rest of your comments go off on the track of reading too much into my Erlang comments and bit syntax comments, so I don’t think I need to answer them given what I’ve already explained here.
July 4th, 2008 at 9:31 am (#)
A small, tiny correction to the article: there actually *have* been many freely available language-independent message queuing systems, and they’re mostly SMTP MTAs. SMTP has always been the elephant in the room when it comes to message queuing; after all, email itself *is* message queuing, and I can think of many instances where SMTP has been uses as a message queuing mechanism across organisational boundaries, domain registration being one of them with the Nominet Automaton being an example. Of course, the main problems with SMTP as a message queuing protocol are its extremely high latency, reliability, and security.
July 7th, 2008 at 3:12 pm (#)
Keith,
I have thought exactly the same thing about SMTP for a little while now. I’m quite surprised somebody hasn’t taken that ball and run with it to demonstrate a tried and tested queuing model to use alongside REST&HTTP.
Some of the problems I see with SMTP in this aspect are:
1. The paucity of tools to manage mail queues
2. Sequencing
3. Weakness over guaranteed delivery mechanisms (DSN facility, specifically)
I’m not as worried about authentication/encryption, because my feeling of the TLS/SSL mechanisms is that they’re advanced enough to do the job sufficiently. As advanced and developed, as say, HTTP AUTH.
In all, I think proper SMTP message transfer and delivery is probably a bit more complicated than what we see with HTTP+REST. I mean, if you want to do it with a level of certainty that is more than “reliable” and closer to “guaranteed.”
July 7th, 2008 at 9:22 pm (#)
Hi Steve,
I’ll be honest, I haven’t had time to read over all the comments, so this may be a repeat… I agree with all your arguments about how crap RPC for distributed systems.
BUT one of the lessons I learned when building XFire was that most people who were using it weren’t building some large distributed system. They just wanted to get their data out of .NET to Java (or vis a versa) as easily as possible. It was often just two computers talking to each other. In this situation, I think convenience matters a lot more than correctness & scalability. These people will never move beyond what they’re doing. Which is why well SOAP/WSDL took off, none of the other WS-* stuff really did.
So I guess I don’t want to see RPC go away because IDLs make integration so damn easy sometimes. And when I’m doing less than a couple transactions a minute, that really doesn’t matter.
Thoughts? Does it have to be either convenience or correctness? Or is it more of a continuum that you move across depending on your needs?
July 7th, 2008 at 9:54 pm (#)
@Dan: hi, where’ve you been hiding? :-)
I’ve been waiting for someone to ask this question. I don’t think we can ever mandate convenience for all situations or correctness for all situations, and I have no delusions whatsoever that RPC will just suddenly disappear because of something I write, but I do think we need to try as hard as we can to make sure we deeply understand the trade-offs. People accuse me of stating the obvious, but based on what I’ve seen in response to some of my columns, various postings here and there, and on my conference talks, all these details about RPC and distributed systems are news to a lot of folks. The goal of this column, along with the three that preceded it this year and the one that will follow for Sep/Oct, is just to try to look at these issues from a variety of angles and make the topic itself and the issues easily accessible, and thereby hopefully help folks choose the right trade-offs.
July 7th, 2008 at 11:55 pm (#)
[…] Vinoski writes an article critical of RPC approaches. Steve Jones doesn’t agree and explains why in a review of the […]
July 8th, 2008 at 4:36 am (#)
[…] Still, convenience over correctness. (Apologies, Steve, I owe you beer) […]
July 9th, 2008 at 12:56 pm (#)
[…] Vinoski – Published a paper on Convenience Over Correctness which talks about tooling and how it affects choice of service oriented architectures, causing […]
July 9th, 2008 at 9:04 pm (#)
Exactly. The point that is bugging me here is that you haven’t really brought out the tradeoffs that are there in REST. Without that REST seems like a maigc pill and then we have people just implementing REST cos its “hot right now”. Both REST and RPC have tradeoffs and you need to understand both and come to a decision (I have pretty much repeated my self in a comment on the other post).
July 9th, 2008 at 9:24 pm (#)
@anonymous: hey, it’s a column, not a book. I get roughly 2200 words in each issue, but sometimes I stretch it as high as 2500 words (thanks to the flexibility of the wonderful folks at Internet Computing). Trying to fit into that space is difficult, trust me, but it’s not that I want more space, either — longer columns would just mean a different set of challenges.
The interesting thing here is that I believe REST is already documented far, far better in terms of constraints and trade-offs than any RPC-oriented approaches ever have been, and for that matter ever will be. But perhaps if the topic sticks in my brain, I’ll see what I can do with it in a future column.
July 9th, 2008 at 10:18 pm (#)
Fair enough . I guess it was just a rant … REST tradeoffs are better documented but I don’t think they are documented well enough .. and I am afraid that people will first use REST like idiots cos its cool and then suddenly throw it away when they realise its not the dream they had thought it would be.
July 10th, 2008 at 10:23 am (#)
[…] interesting. Didn’t Steve Vinoski recently claim that RPC and it’s descendants are "fundamentally flawed"? If so, why are Google and Facebook not only using RPC but proud enough of their usage of yet […]
July 10th, 2008 at 5:48 pm (#)
[…] developers from making poor implementation decisions which limits the value in re-hashing (Steve, Steve and Stu) RPC rights and […]
July 31st, 2008 at 5:04 pm (#)
Hi Steve,
thanks for the interesting article and the explaining comments on your blog. One thing however is still not clear to me. In which situations is RESTful HTTP the best fit and when are message-queuing systems the preferred solution?
August 1st, 2008 at 2:26 am (#)
@Rainer: the intent of the article wasn’t to explain when to use these approaches, but at the very least, keep in mind that HTTP is basically an application-level request-response protocol while messaging is a lower-level approach that supports asynchronous capabilities such as queueing, fire-and-forget, and publish-subscribe. MQ systems typically have ways to persistently store messages, to selectively receive/filter messages from queues, to send problematic messages to “dead letter” queues, to have multiple applications putting and getting from queues, etc., all helping to create an environment for very low coupling between applications, but with a kind of minimalist approach as far as architecture goes. HTTP, meanwhile, is an application protocol with distinct methods, status codes, intermediation considerations, and state traversal (where the server directs client state via hypermedia), all at the application level. The REST architectural style behind HTTP is pretty specific in its constraints and the system properties those constraints induce, and so RESTful HTTP can be viewed as more architecturally rich and thus more constrained than messaging, but in a good way, given that it obviously can allow and help systems to scale way up.