XML-RPC Specification (1999)
xmlrpc.com
xmlrpc.com
* Incredibly verbose. Even a trivial array value like [1, 2, 3] encodes to over a hundred bytes. I'm convinced the author was not aware of attributes, or for some reason held a grudge against them.
* There's only like five primitive types, so implementations that want to transmit wild and unusual values such as 64-bit integers need to define their own ad-hoc extensions.
* It's written in XML but there's no namespace, and implementations may or may not use namespaces for their extensions. Is an int64 represented as `i8` or `{http://ws.apache.org/xmlrpc/namespaces/extensions}i8`? Depends on which library you're talking to!
* There's a native "date/time" type, but the syntax is unspecified other than being ISO8601-ish. Don't even get me started on timezones, which will probably be in the local time of the server, but might be in UTC or BST or who knows what.
* The XML-RPC spec claims that <string> elements can be used to transmit any character except '<' and '&', including binary data, including NUL. I want you to imagine what that looks like on the decoding end. Your XML parser is just humming along, decoding UTF-8 and lexing some tags, and all the sudden it comes across a big blob of fucking binary data in the middle of the document. Why was this allowed when the spec also defines a <base64> element??
The XML-RPC spec ought to come with a Surgeon General's warning that reading it might give you brain worms.
That is completely unsurprising, attributes suck ass for data, what would XML-RPC even have used them for? Replacing <int> by <integer width=“32”>?
Other serialisation formats make the same choice (e.g. plists) because it’s so much simpler.
> There's only like five primitive types, so implementations that want to transmit wild and unusual values such as 64-bit integers need to define their own ad-hoc extensions.
An issue which, which very much unfortunate, is not exactly shocking. Json would have the same if it had integers in the first place.
> including binary data, including NUL
Nul is a perfectly valid UTF8 character.
> That is completely unsurprising, attributes suck ass for data,
> what would XML-RPC even have used them for?
Instead of this: <struct>
<member>
<name>faultCode</name>
<value><int>-123</int></value>
</member>
<member>
<name>faultString</name>
<value><string>some fault</string></value>
</member>
</struct>
It could have been: <struct>
<member name="faultCode"><int>-123</int></member>
<member name="faultString"><string>some fault</string></member>
</struct>
or even: <struct>
<int name="faultCode">-123</int>
<string name="faultString">some fault</string>
</struct>
-- > An issue which, which very much unfortunate, is not exactly shocking.
> Json would have the same if it had integers in the first place.
XDR (used in Sun RPC) was defined in the '80s and had 64-bit integers. The DEC Alpha line had been out for 5 years or so when XML-RPC was published. It's not like 64-bit integers were unusual at the time. > Nul is a perfectly valid UTF8 character.
NUL is not permitted in XML documents. The XML-RPC spec's explicit directive to allow NUL puts it at odds with standards-conforming XML parsers. <array>
<dict>
<key>CFBundleTypeName</key>
<string>ShapeEditDocument</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.example.shape-doc</string>
</array>
</dict>
</array>
( Taken from[2] )Maybe it's common to design XML schema like this at that time?
[1] https://en.wikipedia.org/wiki/Property_list
[2] https://github.com/robovm/apple-ios-samples/blob/1f6b14ef6e2...
I'm certainly not saying this is how you should do things, but it's interesting to look at and has the feature that messages in one format (like XML) could be automagically transmogrified into another (like JSON.)
https://datatracker.ietf.org/doc/html/draft-ietf-vwrap-type-...
Also, messages that look like a HTML web page at the time also could have made it seemingly easier for developers to work with, and be attracted to use a new platform.
I may be dating myself here, but a lot of folks new to the industry seem to think of anything pre-2000 as a dark time full of greyscale CRTs and dot-matrix printers. While those did exist in the home market, academic and business computing (where most of the advanced tech was being developed) was pretty advanced and a modern engineer would have felt right at home on a mid-90s UNIX workstation.
If you go back further you'll start encountering things like CORBA, which were pretty bad, but had the legitimate excuse of being very early. Remember that the '90s moved fast by modern standards -- CORBA was contemporary with MS-DOS, while XML-RPC was after IE had dethroned Netscape.
[0] https://www.xml.com/pub/a/ws/2001/04/04/soap.html
[1] https://docs.microsoft.com/en-us/previous-versions/technet-m...
The rationale probably being to enable storing XML content in zero-terminated C strings.
The XML heyday is a little before my time, but I think attributes were considered improper design compared to only using tags by purists.
For example in the case the author supplied imagine if you wanted to add a compression type to a member. Your only choice would be an attribute which means that it can only be a string.
<struct>
<member name="faultCode"><int>-123</int></member>
<member name="faultString"><string>some fault</string></member>
</struct>
If in the original you could add a new element inside the member like <compression>
<algorithm>zstd</algorithm>
<dictionary>dict7</dictionary>
</compression>
Not the best example but the point stands. Of course the complaint is valid because while extensibility is valuable you need to weigh it against the cost of the verbosity (both in use and for developers). A <fault> struct may not contain members other than those specified.
This is true for all other structures. We believe the specification
is flexible enough so that all reasonable data-transfer needs can be
accomodated within the specified structures. If you believe strongly
that this is not true, please post a message on the discussion group.
At one point the author did intend to allow elements to contain user-defined children[0], but it seems like their position changed between that mailing list post and the spec update 7 days later.[0] https://web.archive.org/web/19991010205056/http://discuss.us...
I also think that this design was also reasonably well aligned with the internal XML capabilities of Frontier.
The opposite really, half-assed "good enough for me" is also very much visible in RSS.
SOAP was basically XML-RPC++, with namespaces, 4 part harmony, and 8x10 color glossy photographs. It's the codification of XML-RPC adding all of those XML features, data types, and interface definitions. It's also a miracle if there's any interop between different stacks.
I had the "pleasure" of dealing with a few SOAP web services a few times. That stuff was just completely horrible and unusable.
HTML5 became a thing when W3C began insisting that XHTML should be a thing, complete with namespaces and other nonsense. That was peak XML basically. Developers rejected it. Browser vendors and content creators basically stepped in and fixed HTML and CSS properly because w3c could not be bothered to step over the semantics and actually define how that stuff was supposed to behave in the real world (i.e. specifiying the semantics of their semantic HTML).
Come to think about it, there was a whole bunch of things that came out of w3c that essentially was about using namespaced XML: web service architecture, RDF, semantic web, XHTML, etc. All that stuff seems to have faded away into obscurity.
XML namespaces sound like a good idea until you realize that it just means endless verbosity that doesn't really serve much purpose and that really complicates things like parsing. Thankfully, people simply refused to apply that to json. Most json continues to be free of that nonsense. Same with yaml and similar formats. Works great without a lot of namespace urls.
Oh is that why. I had heard that comments were taken out because people were using it for "parser directives" or something vague. This makes a lot more sense (although I'm sure there were all manners of hacks in the comments). Definitely a bullet dodged there.
Elasticsearch is a positive exception. It will happily accept comments.
So some simple XML like
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<detail>
<ns2:SendMessageFault1_SendMessageFault xmlns:ns2="http://bip.bee.kz/SyncChannel/v10/Types">
<errorCode>SCE013</errorCode>
</ns2:SendMessageFault1_SendMessageFault>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
is represented by the following JSON monstrosity: {
"name": "soap:Envelope",
"attributes": [
{
"name": "xmlns:soap",
"value": "http://schemas.xmlsoap.org/soap/envelope/"
}
],
"children": [
"\n ",
{
"name": "soap:Body",
"children": [
"\n ",
{
"name": "soap:Fault",
"children": [
"\n ",
{
"name": "faultcode",
"children": [
"soap:Server"
]
},
"\n ",
{
"name": "detail",
"children": [
"\n ",
{
"name": "ns2:SendMessageFault1_SendMessageFault",
"attributes": [
{
"name": "xmlns:ns2",
"value": "http://bip.bee.kz/SyncChannel/v10/Types"
}
],
"children": [
"\n ",
{
"name": "errorCode",
"children": [
"SCE013"
]
},
"\n "
]
},
"\n "
]
},
"\n "
]
},
"\n "
]
},
"\n"
]
} { "errorCode "SCE013" }
That SOAP envelope is 99% just telling you it's a SOAP envelope, which technically is completely redundant because presumably you'd be aware of the fact that you are talking to a SOAP API. And apparently they had no schema for actually telling you anything meaningful about the error. Which is why it is represented as a string with an error code. That string is the only useful bit of information in the message.Basically the SOAP equivalent of Internal Server Error.
From a parsing point of view it's horrible because all those namespaces need to be resolved and the schemas need to be processed. And of course a lot of those namespace urls don't actually have servers behind them that serve those schemas. Most of those urls never resolved to anything useful at all. The servers that were supposed to host those schemas never existed.
Alternatively you just ignore all that crap and pick the message apart with XPath or a regular expression. That's what I used to do when dealing with SOAP APIs. Most of those APIs were just stupendously convoluted RPC wrappers anyway from some bit of enterprise crap ware. I never could be bothered to treat those systems with the respect they demanded from me. Way faster to just sidestep all that nonsense. Send a message, pick apart what comes back to determine success / failure and move on with your life.
That's why SOAP died. Because as soon as people caught up to this being the optimal way to deal with SOAP, the next logical thing was to get rid of it entirely.
- specs so simple it's incredibly easy to implement client and server in most languages
- good enough for most use case, supports whatever that can be expressed in JSON
- easy enough to inspect, it's just JSON
- not too heavy compared to XML-RPC
- as performant as your JSON serializer/deserializer
- None of the ReSTish philosophical questionings
- understood by developers of any generation: call methods with parameters> - None of the ReSTish philosophical questionings
Adding to this,
- If you ever -do- need to drop to something else (i.e. GRPC, websockets) you're not having to re-translate all of your restishness into commands.
JSON, especially for multi-hop RPC, is a minefield of security and compatibility issues because the spec is too simple in a way, making it very complicated to handle safely and securely.
While yeah it’s pretty dated by modern standards at the time it was a revelation that you could build standard-based APIs that anyone could use with a simple library and without having to write a TON of custom code.
And regardless, it was far easier to implement than SOAP, which was just a mistake unless you are fully immersed in the Java ecosystem.
Later, those bindings made it into very early Drupal core[3] and onto thousands of websites. In this era, you could make desktop apps talk to websites using an XML-RPC gateway — for content management or many other tasks.
Yes, XML and related tech is fairly horrible, but context is everything.
If you were running servers, there was enormous pressure to use Microsoft.
If you were by chance running open source (LAMP stack), making applications work together was a challenge. Interoperability was not the norm, despite a pretty rich internet. Formats and standards were the problem.
You would email code patches around. There was no GitHub, and SourceForge was only starting to gain traction.
If were using open source version control in this era, you were likely on CVS, which was an "improvement" over RCS, but still nothing like the promised future tech of Subversion, which wasn't text-backed. Text-backed! Versions of files were concatenated, and instead of force pushing, you opened this concatenation abomination in a text editor to hack the repo history (if you were a bad, bad person, but needed to get the job done).
As mentioned many other places in this thread, if you were doing open source interop, the heavyweight option was SOAP. XML-RPC was as much a breath of fresh air as JSON is to XML.
Fairly-literal text was bloated, slow, and XML even more so, but it was all pretty cutting edge for the time.
[1] https://www.xml.com/pub/au/11
[3] https://git.drupalcode.org/project/drupal/-/blob/4.0.x/inclu...
Many developers here might not recall serious compatibility issues with Microsoft- the most obvious one I recall was WebDAV ; pretty much strangled at birth by MS terrible broken implementation.
I used to use the PHP XML-RPC implementation you worked on for so many projects, so thanks for that- helped me to integrate so many projects, so cheers!
I wrote a service to allow BSD servers running Python apps to run SQL queries on a Windows server running Visual FoxPro, and everything at the time said SOAP is what you use for such things. That was overengineering writ large. After a while I replaced it with XML-RPC and life got much easier.
If JSON had widely existed at the time, and someone would have shown it to me, they would’ve been my friend for life.
My thinking is: if you employ a relative high-ceremony meta-language such as XML as service payload format, then you'll at least want to use its features to model free yet strictly validated information exchanges (such as ASN-based protocols have been doing). But xml-rpc doesn't give you that and imposes param=values logic known from simple URL-encoded invocation forms instead, improving little over those.
Then SOAP was introduced as the big unified payload serialization format covering document- and RPC-oriented uses. We all know just how it sucked.
But then came the even worse end result/eternal September of "REST" APIs - a misuse of HTTP and blatant and painful misappropriation of Fielding's concepts, whose proponents used SOAP's flaws as an excuse for their anti-engineering practices.
I wrangled XML-RPC and SOAP back in the day. It was bad enough when you had exactly the same stacks talking to each other. When you had to interop between systems, ie .NET talking to Java, which was half the point of it all, it was a whole new circle of hell.
I still get mild PTSD from thinking about XMLsec and XML c14n.
I used XML-RPC exactly twice, but it proved to be a quick solution to nasty integration problems and we were very happy with it.
Case #1 - we had to implement an interface to book flights on Amadeus (https://amadeus.com/en). In order to guarantee the caller identity they provided a C library (binaries that you had to link with your stuff) that would generate tokens that you would then add to your own calls to them to guarantee your identity. We were trying to use it from a Solaris machine, and the library would bomb at each call. But their Windows binary module worked fine, so we basically put up an XML-RPC connection between our Solaris hosted main app and a little Windows service which would simply provide the token for us to embed in the subsequent call. (This was the only way we could find to hit our release date in time, and it worked fine for 5 years serving hundred of thousands of calls every year).
Case #2 - less "business critical", but still fine: I was on sick leave from the office recovering from minor trauma to my knee and here is what I suggested to a guy trying to use a PERL library as part of non-PERL stack: https://stackoverflow.com/a/2635719/54504
(it was part of his final exam for a degree in CS, I provided more assistance outside of StackOverflow and he was very happy with the results).
But just that SOAP sucks doesn't mean "REST" is ideal. Fallacy of the excluded middle and all.
It not being a rigid protocol was a boon for web development although it generally meant "REST" was so nebulous people would describe their usage as "REST-like" or "REST-ish" if they broke conventions (like just using POST for most payloads)
But I'd say most of all it took off because it was simple and people like simple, particularly after jumping through hoops for a decade prior.
That's kindof the problem:
Except in the case where a thin browser front end is rendering a single response payload transferred by necessity over HTTP a la XSLT (which we're not doing anymore for better or worse) there's absolutely no rational reason to stick to "REST principles" in quasi-religious manner and exegetic interpretation of Fielding's thesis that coined that term. In fact, I'd say it's counterproductive, because a simplistic "REST" facade doesn't even begin to describe the actual interaction between backends or rich frontends and backends, those interactions often being stateful and much more involved and granular than sending back-end-forth idealized full "representations" or flawed over-exposing ideas of the nature of a backend concept. You might think that SOAP-like UpdateOrderLineItemBilling granular ops suck, but these are much more representative and telling than coarse pretentious REST APIs suggesting you could update anything at any point in time during the course of a process, when in reality backend logic just doesn't work that way (eg in the ecommerce example, you'll have to honor the delivery and billing status of items to cancel, and compensate or retour items accordingly, etc).
Really, "spiritual programming" isn't an engineering discipline; you can model your backend-to-backend interactions freely without having to appeal to concepts from HTTP taken completely out of context.
No? There is no relationship between the two. XMLRPC is a straightforward application of XML, its intended niche was similar to JSON(RPC): point the client at an endpoint and go to town.
And if you were using Ruby or Python it worked nicely, and still does really.
Given the alternatives it really seemed like a lesser of the three/four evils.
Not sure if any ever existed. Of course, I'm unsure if XSDs were much used outside of big Java shops.