It’s just data

Trade-offs

Leonard Richardson: Are all these architectures mutual opposites, or points on a gradient?

My answer: neither.  But before we get there, indulge me for a moment.

Let’s start with aa.com.  If you go to that page, actions made available to you include a FlightSearchUpdatePreferredCities, and the ability to request gatesTimesStatus.

Each are done with HTML forms.  Each are done with HTTP POST, even the queries.  Each are request/response.  Each passes a number of input parameters along with the request.  A common paradigm for HTML forms is for buttons to be used to determine the action taken — and this is also transmitted as an input parameter value.

This should sound familiar.  These are forms of remote procedure calls, implemented using HTML over HTTP.  Request parameters, and even the action selected, may be included in either the URI itself, or in the POST body.  Both approaches are common practice, and both are well supported by the various browsers and servers that implement these protocols.

Is using POST for such actions a best practice?  Not if you want to be able to bookmark a search result.  But given the way that this particular application uses URL rewriting techniques to implement a session, bookmarking isn’t really practical for this service.  That’s a trade-off that they can chose to make.  After all, using HTTP GET involves a different set of trade-offs.

Now, lets look at an XHTML document, containing an SVG circle:

<!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
    "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
<html xmlns='http://www.w3.org/1999/xhtml'>
  <head>
    <title>Circle</title>
  </head>
  <body>
    <svg xmlns="http://www.w3.org/2000/svg">
      <circle fill="#009" r="45" cx="50" cy="50"/>
    </svg>
  </body>
</html>

This document is described by a DTD, contains a head with some metadata, and a body.  It can be processed by a DTD aware tool, can be treated as Plain Old XML, produced by a template, or simply entered into notepad.  I created it using vi.

Now lest take a look at a SOAP document, containing the same SVG circle and a somewhat randomly chosen header:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Header>
    <path xmlns="http://schemas.xmlsoap.org:rp/">
      <id>uuid:09233523-345b-4351-b623-5dsf35sgs5d6</id>
    </path>
  </Header>
  <Body>
    <svg xmlns="http://www.w3.org/2000/svg">
      <circle fill="#009" r="45" cx="50" cy="50"/>
    </svg>
  </Body>
</Envelope>

First note that there is no DTD provided (in fact, such is not allowed), nor is there any schema references (such is entirely optional).  Like the XHTML document above, it also contains a Header with some metadata and a Body.  If a separate WSDL document were provided, this document could be processed by an XML Schema aware tool, but it can also be treated as Plain Old XML, or produced by a template, or simply entered into notepad.  Again, I created this particular document using vi.

Contrary to what some will lead you to believe, I submit that it is possible for a query to be simultaneously SOAP, REST, RPC, POX, and transmitted using HTTP POST.  And all this could be done with or without a WSDL document or an XML schema.  Furthermore, both ends of the wire don’t have to agree.  I can create a request using POX techniques and send it to an interface fully generated from a WSDL document containing a full XML schema and implemented using the Windows Communication Foundation.

I maintain that POX is not an information format style, but rather a set of techniques for producing and consuming XML.

In any case, the point is that doing any of the above involves trade-offs.  Often we are talking about trade-offs that you are not even aware that you are making.  Again, one such trade-off is “if your application routes based on either an HTTP header or data within the payload, then your users will not be able to bookmark the request”.  Another is “if you implement unsafe operations using HTTP GET, bad things will happen if your pages get spidered”.

Yet another trade-off I consistently see is the desire to treat XML as merely a serialization format, not as a document lovingly crafted by humans.  Ask current versions of Microsoft Word to save a document as HTML, and you will often get a document that simply is not fit for human consumption.  You can achieve similar results using yacccamping.rb proves that a certain class of humans can also produce such output too.

CORBA is based on the notion of generating implementation from IDL documents.  Conventional wisdom is that this works best if both ends of the wire are based on CORBA implementations from the same vendor.  The situation is a bit better in WS-*, interop works best when the WSDL is generated from an implementation and if the vendors who provide each end of the wire have actively participated in pairwise interop testing.  Those that merely attempt to produce compliant WSDL based on the available specifications often find problems such as these.  But the siren call for viewing the programmable web as merely a serialization format seems unstoppable: the current incarnation is called WADL.

Despite using HTTP POST, the aa.com example above is not only RESTful, but it is of the web.  If you were to map out the entire application, you would find a state machine, one that humans or bots alike can navigate by real or virtual mouse clicks.  The nodes in the state machine are mapped to URIs.  The URIs are connected via hypertext links.  These links generally are not found in HTTP headers, but in the payload of the documents themselves.  This approach is called Representational State Transfer.

BPEL4WS using SOAP is an alternative.  An alternative that is typically web in name only.  The messages involved don’t tend to contain anything resembling a hypertext link.  State is not transferred in representations.  What you have instead is a discrete set of endpoints whose activity is choreographed by an external agent, one that manages the overall state of the system.  A different approach.  One that reflects a different set of trade-offs.

Finally, Sanjiva brought up WS-Security.  If you find yourself needing to sign and encrypt SOAP requests and responses using X509 certificates, you will find that it is implemented interoperably by a handful of vendors.  Others may find that they can achieve the levels of security they need using PGP.  And despite the fact that it is limited to being point to point, amazon.com finds SSL more than sufficient for transferring credit card information privately and securely.

It is my hope that this book will be an eye-opener to many.


The Web is based on traversal, so all messages are self describing. What’s missing in this example are HTML forms that tell you where the resource is, and what inputs to supply.

I prefer that example because it looks like functional programming, whereas SOAP is strictly object access.

If you draw a parallel between Ruby and Java, that’s your own imagination :-)

SOAP is endpoint oriented. There’s a limited number of endpoints and all the information is known in advance. Great when those endpoints are hard to manage (I believe it’s called governance).

Can they overlap? Yes. Due to an interesting characteristic of technologies: they’re both particles and waves. You can always find examples where Java looks like Lisp and HTML smells like Swing.

The inference pattern of WS-* and REST is very strong in the presence of WS-Transfer (aka HTTP over SOAP over HTTP) and WS-Addressing that provides some form of representational transfer.

But once you go that route, the protocol abstraction starts leaking. If you want to send state around, it might be a URL or a wsa:endpointReference. Implementation details?

Well, those states go in the body of the message, so they affect the interface. How do you move from REST to POX to SOAP when messages contain locations?

Posted by assaf at

Which seems closer to existing usage of “SOA”, insofar as “SOA” means anything besides “your new issue of BusinessWeek is here.”

I am so buying this book when it is done.

Posted by Bob Aman at

The Wave Function of SOAP and REST

My sub-atomic particles are always in a mess. You see, they’re actually waves, so you can never be certain where you left them. They’re here and there all at the same time. Just like software. And I’m not talking about the...

Excerpt from Labnotes at

Sam Ruby - Trade-offs: "Contrary to what some will lead you to believe, I submit that it is possible for a query to be simultaneously SOAP, REST, RPC, POX, and transmitted using HTTP POST. And all this could be done with or without a WSDL...

Excerpt from Tim's Weblog at

Links - 11.07.2006

Trade-offs Sam is converging on a very data-centric model of web services. In this model it’s the data that matters and the architectural model/protocol (REST, SOAP, POX) is an implementation detail. Personally, I think this is a really bad way to...

Excerpt from discipline and punish at

First: Sam, what’s going on with the non-breaking spaces riddled throughout many of your articles and comments? Is something borked in your washy-washy-routine? And what’s going on with the design on your comment preview page?

Second, I completely agree with you. I do have a small comment on the problem Simon Fell had, though. He writes:

<s:element name="ValidFrom" type="s:dateTime"/>
[...]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.w3.org/2001/XMLSchema")]
[System.Xml.Serialization.XmlRootAttribute("ValidFrom", Namespace="http://test.sforce.com/", IsNullable=false)]
public class dateTime : System.Web.Services.Protocols.SoapHeader {
    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string[] Text;
}

Huh, why is the value a string array and not a DateTime?

The problem here is that .NET 1.x does not allow for simple types like DateTime, Integer, Double, etc, to be null. When creating a class based on a WSDL that allows nullable simple types, .NET needs to use an Array of the given type to be able to assign {null to it. Why this exact example becomes a string array, is beyond me, but in .NET 2.0 you can have nullable simple types as well, which are declared with the int? syntax. So with .NET 2.0, Simon wouldn’t have had this problem.

However, it is as you say, always better (and easier) to create a WSDL from a working service than to create a working service from a WSDL.

Posted by Asbjørn Ulsberg at

what’s going on with the non-breaking spaces riddled throughout many of your articles and comments? Is something borked in your washy-washy-routine?

When I was taught how to type in the late 1970’s, on a manual typewriter no less, I was told to put two spaces after the end of a sentence.  When I wrote my “washy-washy-routine”, I implemented this by changing the first space in a multi-space sequence into a non-breaking space.  I realize that fashions change, but this is my “washy-washy-routine”.  :-)

And what’s going on with the design on your comment preview page?

Not much.

However, it is as you say, always better (and easier) to create a WSDL from a working service than to create a working service from a WSDL.

That’s not the way it is supposed to work.  The end result for the typical PHP service provider is something like this: “it is always better (and easier) to document the wire level protocol in human comprehendable terms, and then to hand code the strongly typed Java and C# libraries for producing and consuming this data”.

Posted by Sam Ruby at

Sam Ruby: Trade-offs

[link]...

Excerpt from del.icio.us/tag/rest at

When I was taught how to type in the late 1970’s, on a manual typewriter no less, I was told to put two spaces after the end of a sentence.

There seems to be an ongoing debate about how many spaces to put after a period, but there is no debate at all that “1970s” does not require an apostrophe.  (See also: The apostrophe is the modern day Shibboleth, Bob’s quick guide to the apostrophe, Apostrophe Protection Society.)

We now return you to your regularly scheduled flamewar about where to put the blank line in your web services.

Posted by Mark at

Asbjørn, I’m afraid you’re assertions about .NET 2.0 are wrong, see [link]

Posted by Simon Fell at

When I was taught how to type in the late 1970’s, on a manual typewriter no less, I was told to put two spaces after the end of a sentence.  When I wrote my “washy-washy-routine”, I implemented this by changing the first space in a multi-space sequence into a non-breaking space.  I realize that fashions change, but this is my “washy-washy-routine”.  :-)

I see. I also see that the problems caused by it is in fact Opera’s (9.10 beta) fault. So never mind. :-)

And what’s going on with the design on your comment preview page?

Not much.

This is too caused by a bug in Opera 9.10 beta, I guess.

That’s not the way it is supposed to work.  The end result for the typical PHP service provider is something like this: “it is always better (and easier) to document the wire level protocol in human comprehendable terms, and then to hand code the strongly typed Java and C# libraries for producing and consuming this data”.

True. I’ve always had most success with an existing implementation (perhaps just at the XML level) and then getting the different services to work on top of the WSDL produced from it in at least two different environments (usually .NET and Java). With PHP, “everything” works anyway &mdash; that’s at least my experience.

Asbjørn, I’m afraid you’re assertions about .NET 2.0 are wrong, see [link]

Hm, that’s odd. If I were wsdl.exe I would definitely construct that as a DateTime (considering, as you wrote, it’s in fact not nillable). I did some testing on the schema portion of the WSDL, and by wrapping the add, TestResult and ValidFrom types in another complex type as a container, wsdl.exe had no problems constructing ValidFrom as public System.DateTime ValidFrom inside the containing class. So the problem here isn’t with nillable types at all, but with non-contained simple types. That’s at least my preliminary conclusion for now. :-) Just for laughs, here is the schema with the container element in place:

<xsd:element name="container">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="add">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element minOccurs="1" maxOccurs="1" name="a" type="xsd:int" />
            <xsd:element minOccurs="1" maxOccurs="1" name="b" type="xsd:int" />
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="TestResult">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element minOccurs="1" maxOccurs="1" name="addResult" type="xsd:int" />
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="ValidFrom" type="xsd:dateTime"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

This probably won’t solve your problem, but it might explain it.

Posted by Asbjørn Ulsberg at

links for 2006-11-09

Java IAQ: Infrequently Answered Questions (tags: java FAQ iaq reference) JSESSIONID considered harmful (tags: java security servlet jsessionid session j2ee HTTP) Re: RFC for REST? Roy T. Fielding on the early history of REST and HTTP (tags:...

Excerpt from protocol7 at

I see. I also see that the problems caused by it is in fact Opera’s (9.10 beta) fault. So never mind. :-)

It doesn’t look like Opera respects the DTD.  Truth be told, I’m not all that thrilled relying on the DTD anyway, so that part I’ve fixed.  All the other problems I see remain unfixed.

Posted by Sam Ruby at

Return of the Son of Taxonomy of the Programmable Web

Previously, on Taxonomy of the Programmable Web, I put out a description of the Resource-Oriented Architecture based on its answers to these two questions: How is the request scoped? How does the client tell the server what part of the application...

Excerpt from News You Can Bruise at

[from jonas] Mark Pilgrim on Sam Ruby: Trade-offs

“We now return you to your regularly scheduled flamewar about where to put the blank line in your web services.”...

Excerpt from del.icio.us/network/f_meyer at

More news from around the web

Sam Ruby and Leonard Richardson are writing a book comparing Web Services to RESTful services. We want to restore the World Wide Web to its rightful place as a respected architecture for distributed programming. We want to shift the focus of...

Excerpt from Category 4 Blog at

Does REST need a WSDL?

First read this (written by Marc Hadley ) "This article describes the Web Application Description... [more]

Trackback from alexbarnett.net blog

at

Does REST need a WSDL?

First read this (written by Marc Hadley ) "This article describes the Web Application Description Language (WADL). An increasing number of Web-based enterprises (Google, Yahoo, Amazon, Flickr - to name but a few) are developing HTTP-based...

Excerpt from alexbarnett.net blog at

Add your comment