A recent mailing list thread brought up on XMLRPC vs SOAP vs REST and so forth, and I noticed there were not a lot of articles on Google about this that really addressed some of the high points. I figured I might as well be on Google too, so here is my opinion.
This is based on not only a few apps like Cobbler and Func, but also past work where I’ve touched almost all of these first hand — I always seem to get stuck working on the backend server components wherever I go. This is by design — I like it there.
So here are the plusses and minuses to everything, and I’ll put a mark beside all the ones I’ve used before. Hopefully this will provide useful ammo if someone faces the “you must use SOAP” mandate somewhere and is looking for good options — or for people who are just looking for additional data before making a choice.
XMLRPC:
+ easy to route around firewalls
+ has very nice libraries available in a wide array of languages that make it feel just like a locally used library
+ widely used in for systems management type applications
+ simple libraries exist that do not require a “web app” stack to be a server for it
+ does provide a mechanism for signaling remote faults and raising them in the caller
+ while it is XML based the user doesn’t have to care about the XML, auto-serialization is an awesome thing to have.
+ specification has been around for a long while and has not needed to change, which means it got most things right
+ easy to proxy security behind Apache and let it take the heat
- serialization works for basic nested data structures of normal types, so your API must be written to use basic datastructures or otherwise serialize data in XML. (Basic datastructures are fine for most applications)
- does not have a bool type and typically cannot represent “None” (NULL) without special parameters as it is not in the spec — but this can be designed around easily. Should None be in an API? Probably not.
- is not deemed as “enterprisey” by some people as SOAP if you must deal with developers who like things to be called “enterprisey”
- not good for transport of large files because it ships things as XML.
REST:
+ easy to route around firewalls
+ useful for uploading files as it can be rather lightweight
+ very simple if you just want to shove simple things at something and get back an integer (like for uploaders)
+ you get it for free in some web application stacks and it is easy to pitch to “mash up” style web developers
+ easy to proxy security behind Apache and let it take the heat
- does not define any standard format for the way the data is being exchanged (could be JSON, YAML 1.0, YAML 2.0, arbitrary XML format, etc)
- does not define any convention about having remote faults sent back to the caller, integer codes are frequently used, but method of sending back data is not defined. Ideally this would be standardized.
- may require a lot of work on the client side caller of the library to make use of data (custom serialization and so forth)
- not pitchable as an enterprisey API in most cases, unless you are talking to web developers
SOAP:
+ easy to route around firewalls
+ widely used in for systems management type applications
+ supports complex objects if you absolutely need them and don’t mind writing a lot of code for it
+ has crazy things like envelopes
+ does provide remote faults and raises them in the caller
+ easy to proxy security behind Apache and let it take the heat
- has crazy things like envelopes
- pretty high signal to noise ratio in wire format, might be a slight performance concern
- caller will probably have to do work to process return data and format objects correctly
- typically only has good libraries for “enterprisey” languages, though there are some nice looking exceptions
- not everyone understands all of it
- lots of related and optional standards are confusing and sometimes not complete
- typically causes dynamic language hackers to run screaming when it is mentioned.
- in most cases, all you really needed was XMLRPC anyway
- .NET tools say they speak SOAP, but if you look at the underlying implementations, they are encoding data in a giant XML glob inside the stream, making it only really work for .NET apps. Embrace and extend here, so if you are picking SOAP for compatibility with .NET apps, they speak a different language that isn’t really in the spirit of the game.
CIM
+ Well supported by major players in the systems management space, allows you to do things with their software
+ Supported by a lot of storage and server related stuff
+ Definitely holds up as “enterprisey” if you need to play in that sandbox
- Way too complex for most developers to be efficient in it, or even be able to use it
- Not a lot of good dynamic language bindings, if any
- Hardly any implementations of it doing anything useful
- It’s hard to not code to a specific implementation and make things portable.
- Poor (free) documentation, especially in terms of examples. Good documentation seems to require payment of fees and being on commitees.
- open implementations leave some things to be desired (memory consumption)
- lots of related and optional standards are confusing and sometimes not complete
- not really adopted much in the open source space due to barriers of entry
- typically causes dynamic language hackers to run screaming when it is mentioned.
WMI
- This is microsoft stuff and is not happily cross platform
WS-Man and WSDM
- Other attempts to redo CIM
- Still painful
- Most of the same problems
- In many cases, even less adoption
RMI
+ Feels like a local API, much like XMLRPC
+ Can provide some fairly nice remote exception data
- Java specific means this causes lock in and limits your options
- Has horrible versioning problems between different versions of clients
- Skeleton files must be compiled in like CORBA, which is not very flexible
- Serious pain in the ass to multiplex sockets and secure them
- Subjective, but feels like it blows up a lot.
- While this is Java tech, it’s not “enterprisey” if you need that. Not anymore.
- Not firewall friendly (with exemptions, but they are pain)
CORBA
- Dinosaur tech. Very similiar to RMI.
Custom Socket Server implementations
- You will get the security part wrong.
- People will have a hard time talking to you.
- You will make extra work for yourself.
- It’s a bad idea.
Just send commands as INSERTS through the database
+ This might be ok for some batch job kind of things
- Not really an API, too much access to maintain
- Unsuitable for remote or untrusted/read-only usage.
Just FTP files around into an “orders” directory
- Even worse, don’t do this either. This does not an API make.
DBus
+ Great for local communication on the desktop on Linux
- Has a fair amount of dependencies
- Not something you (edit: typically) use remotely
Your Favorite Message bus (This post is not about message buses)
+ Nice if you want to address multiple things at a time and need complex routing options, especially if you are building it for a datacenter type setup where you control everything
+ May be very fast
+ Can be called “enterprisey” if you need that
- Can be a bit difficult to deploy and configure for your users in some cases
- Not all of them have a wide variety of language support and therefore may create lockin (thankfully AMQP does and does not have this problem!)
- Probably not right if you are writing multi-platform code
Conclusion? I like simple code that gets the job done while still covering all the bases I need to cover. I don’t need it to cover ALL of the bases, just some of them.
I like XMLRPC because there are very good client libraries, standardizes it’s serialization formats (and handles this all behind the scenes), does not show a language bias, and makes things trivial for the caller — it looks just like a local API. If your marketect demands, you can call it a full fledged web service with a straight face — it is one — for instance, the Python API’s provide a way to enumerate remote methods just like WSDL does (or close enough). There are some things it is not perfect at, but in the Linux space, it is omnipresent and very easy to use, and I like things that allow me to build infrastructure with the bare minimum of work and access it from multiple places without too much lock in. It is also a simple standard that you can read and instantly understand, it does not hide behind any hard to obtain knowledge that makes it seem superior.
Now, you don’t have to do just one API format — You could do something clever and expose things more than one way, too, but that’s extra work and I like to be minimalistic.
Other people may have their own preferences. That’s ok.
Google: have at.
Corba really would deserve more than just “dinosaur tech”. Although it is old and developing with Corba can mean a lot work the outcome can be extremely good. Early binding and actually paying attention to the details, and the performance is plain superior. Nearly nothing matches the speed of properly done Corba. Especially if compared to REST/XML-RPC stuff it can be 10-500 times faster, depending on what sort of data you are wiring.
AMQP seems to solve that and gives you more ways to access it.
When discussing the benefits of XMLRPC, you mention …
> does provide a mechanism for signaling remote
> faults and raising them in the caller
Aside from looking at the koji source, I’ve yet to find a solid example of doing this. Have any tips/pointers?
James,
Yes, you don’t get the exact same fault, you just get a remote fault that contains the string name of the fault on the other side.
On the remote side, any method that includes a “raise” will result in an exception on the other side, and you can tell what happened. But no, you don’t get the full stack trace.
For instance:
def remote_method_foo(self,a,b):
if a == 1:
raise FooException(“hell”)
return b
On the client side:
try:
print server.remote_method_foo(1,2)
except xmlrpclib.Fault:
print “ouch”
http://www.python.org/doc/lib/fault-objects.html
Good summary; RPC is a vast field.
Two comments -
First, DBus can be used over TCP and is actually a good option when you want a more flexible option as opposed to the fixed request/reponse semantics of HTTP. For example, when you want notifications. XMPP is another choice in that area.
Second, have you looked at Google’s Protocol Buffers or Facebook’s Thrift (I haven’t, but have heard good things about both).
I stand corrected then
Yes, I forgot to mention XMPP (Jabber protocol). XMPP can definitely be used as a message bus. If you really really want to, for simple apps, IRC bots can be used for the same (not recommended).
I looked over the Protocol Buffers thing, it seems to be ok on the wire format and the .proto format, but still needs generated code. If it /didn’t/ need generated code I’d find it more interesting though I see they are targetting Java and C++ land too.
Haven’t looked at Facebook, as I had thought it’s a bit of a walled garden. No real experience there.
One small mistake here. You speak of xmlrpc:
“- does not have a bool type”
but it does have a bool type
http://en.wikipedia.org/wiki/XML-RPC#Data_types
Great article!
Corrected. Not sure why I thought that…
FYI, there’s an extension to the xml-rpc spec that supports the notion of as the XML-RPC type equivalent for None/undef/NULL:
http://ontosys.com/xml-rpc/extensions.php
Supposedly Dave-Thomas-approved, just doesn’t seem to have made it into any code-bases that I’m aware of…
Other than that, the only other area that seriously irritated me about the standard spec was the fact that Faults only really have a code, and a text entry. There have been a few times where a “label” field in the fault object would have been really, really useful.
I’m pretty sure allow_none in Python uses that extension.
(Not sure how Dave gets to be an authority there?)
if you compare with SOAP only ok, xml-rpc are realy suffisant, and rest to!
but SOAP is the base of WS standard… not all the standard…
but if you need more control on what you do with your services:
* cartography
* monitoring
* sla
* authorization/authentication centralized
* reliable massaging
* transaction
* …
soap:
+ not limited to http protocol
+ transaction support
+ reliable transporting mescanisme support
+ many tool, application supporting it natively… like appliance reverse proxy (can do SLA monitoring or inforcing), soap router, ESB, EAI, corporate software…etc…
+ all the major industry giant player are behind (IBM, Microsoft, Oracle/BEA …), standardized by W3C and OASIS.
+ many developpement tool to develop WS.
and interoperability is ok if you start on WSDL to generate code… and not the reverse… and you use only Document Literal, and not RPC soap style!
corba:
ok is dinozorus tech!
but use binary format to exchange data, is good for perfomance… but is bad for troubleshooting… and IIOP protocole are not completely standardized…
and pass very badly firewall…
but corba, have many enterpise feature like transaction.
SOAP are reingenering many of use…
you miss EJB the J2EE clone of corba…
and many other thing…
the subject are very vast…
Matthieu,
Naturally those examples are reasons SOAP has gone WAAAY too far. Those sort of extensions are more reasons to avoid it. Note that SOAP is only one of many web services, so it is not “THE” WS standard… the great thing about standards is there are so many to choose from
Many of the added features you mention are used to sell high-buck software but they do not help get real actual work done. By over-complicating software, we raise the cost to produce it and we reduce the ability for the community to work on it. Therefore, SOAP is a dismal failure in this respect — which is why you see such bad adoption in the open source space.
EJB tries to be a lot more than just a CORBA clone. The immense overcomplexity of such is why you see such uptake of technologies such as TurboGears, Django, and Ruby-on-Rails. It is simply not an efficient development environment.
[...] his entry XMLRPC vs REST vs SOAP vs CIM vs RMI vs Message Bus vs … Lots of RPC Options, Michael DeHaan opens his experience with RPC protocols and pours it out on the page. This is based [...]
Missed coverage of AMF3?
[...] public links >> datastructures XMLRPC vs REST vs SOAP vs CIM vs RMI vs Message Bus vs … Lots of… Saved by katiehbr on Sat 25-10-2008 Data structures are important (or maybe I’ve just wasted my [...]
[...] public links >> datastructures XMLRPC vs REST vs SOAP vs CIM vs RMI vs Message Bus vs … Lots of… Saved by katiehbr on Sat 25-10-2008 Data structures are important (or maybe I’ve just wasted my [...]
When talking about SOAP it is critically important o distinguish between rpc/encoded and document/literal.
rpc/encoded is extremely verbose and unwieldy
document/literal is a much more efficient and flexible format.
so your assessment above should really treat these two flavours of SOAP as different and assess them individually.
Let’s say I have a population Linux embedded appliance on a LAN behind a typical firewall and a large central server monitoring status of all these appliances, but also sending asynchronously commands to these appliances. The appliances can always report status to the central server since it has a well-known address. Do any of these protocols support an open connection that would allow the central server to asynchronously send commands to the appliances? I understand JSON-RPC over sockets fits this requirement. Others?
Depends on what large is? If it’s a monitoring app, something like collectd might work better fit.
Not sure you’d want to leave that number of sockets open all the time anyway. (UDP!)
Messaging is also nice to send commands to nodes that might be offline or temporarily unreachable. In the case of mobile devices, they won’t always be able to be contacted.
Just one more piece of perhaps-exotica to throw in, or perhaps the wave of the future: IIRC the jabber server was originally written in Erlang. Erlang is a programming language built for distributed processing, either locally within a trusted network or across the network with a more secure protocol. Its design objective was to handle thousands of threads on multiple processors, and ‘never’ go down.
I am just learning Erlang now – it’s a very different programming model and syntax than I am used to but I was able to build a simple server-and-client passing messages back and forth as my second toy project, that took under an hour – with the help of the book!
Total lines of code = maybe 30.
Erlang’s programming model obviates most problems encountered when working with multiple threads and processes. Once I got my head wrapped around it, it’s easy to program in, at least as far as I’ve gotten.
Gary, yes, allegedly it’s good at concurrency, but the question is whether it’s just a current fad or not. Jury is still out, I think.
Doesn’t change the discussion of interconnects as that’s mostly a discussion of languages to write the program in, not which standard to pick, no?
[...] Karsten ‘quaid’ Wade In his entry XMLRPC vs REST vs SOAP vs CIM vs RMI vs Message Bus vs … Lots of RPC Options, Michael DeHaan opens his experience with RPC protocols and pours it out on the page. This is based [...]
Thanks for the helpful summary. Really appreciate it from the standpoint of a newcomer’s to these technologies who needs a quick but well-founded decision on which architecture to build on.