Monthly Archives: July 2002

XML Schema derivation

XML Schema derivation by extension superfluous?. Don falls for derivation by restriction one more time. [Don Box’s Spoutlet]

While I was just trying to round out some ideas related to the schema and web services discussion we’ve been having, I came across this post from Don.  Very pertinent to what we’re talking about, relative to extending a schema when it contains xsd:any extensibility elements.

When we derive by restriction, we are guaranteed that any valid document matching the new schema will also validate against the original schema.  This is what I was trying to describe below…just not as succinctly as I might have.

Sam Ruby on Loosely Coupled Web Services

New essay: Expect More.  [Sam Ruby]

Sam writes an excellent essay on upward and downward compatibility with web service contracts.  If I might paraphrase for context, he holds that we should be able to add or remove parameters from a web service contract, without adversely affecting existing clients (note he says a lot more than this – read the article!).

I tentatively agree with Sam; but only in the case where the new request can be validated by the WSDL-contained schema.  If you send me a new element I’ve never heard of, and I can’t validate your request document against my schema, I don’t consider it a valid request.  If you omit something, and my schema says it’s required, invalid again.

Here’s an example of where I believe your rules could get you in trouble.  Suppose a service to book an airline flight (coach only in v1), with the request schema:

<s:schema targetNamespace=”http://sample.org/“>
  <s:element name=”BookFlight”>
    <s:complexType>
      <s:sequence>
        <s:element minOccurs=”1″ maxOccurs=”1″ name=”Airline” type=”s:string” />
        <s:element minOccurs=”1″ maxOccurs=”1″ name=”FlightNum” type=”s:string” />
        <s:element minOccurs=”1″ maxOccurs=”1″ name=”Origin” type=”s:string” />
        <s:element minOccurs=”1″ maxOccurs=”1″ name=”Destination” type=”s:string” />
      </s:sequence>
    </s:complexType>
  </s:element>
</s:schema>

And a valid request document matching the above schema (SOAP headers omitted):

<BookFlight>
  <Airline>UA</Airline>
  <FlightNum>1234</FlightNum>
  <Origin>DEN</Origin>
  <Destination>SEA</Destination>
</BookFlight>

Now suppose you send me a document that also includes a “ClassOfService” element:

<BookFlight>
  <Airline>UA</Airline>
  <FlightNum>1234</FlightNum>
  <Origin>DEN</Origin>
  <Destination>SEA</Destination>
  <ClassOfService>First</ClassOfService>

</BookFlight>

As I read Sam’s rules, this should be allowed and be processed exactly as before.  Now, suppose version 2 of my flight booking service supports booking in first class as well as coach.  If I add a “ClassOfService” element, which takes ‘F’ or ‘Y’ as the parameter, your document may now give unexpected behavior. 

For cases like these (and many more that I could come up with), I believe that loosely relying on the schema is a bad idea.  I think you should only extend the request in places where the schema specifically allows it; in the case above, if there was a xml:any extensibility element, you’d be fine, and you could put your extensions there.  If you want to omit parameters, you can only omit the ones allowed by the schema.

Sam mentions explicit extensibility points at the end of his article, but I got the impression he meant that while these were a good idea, we should allow the request extensibility even without these mechanisms.  Very-loose coupling might be ok when we’re searching for books; but when we’re doing financial transactions or other sensitive transactions, I think we need to be very specific about what we’re doing.

Otherwise, I think that’s just asking for trouble.

XML Web Services

Regarding my previous post about adding methods to web services without changing the version/namespace, Brad had a good comment:

The thing you have to be careful with is new clients against old servers. While the consequences aren’t necessarily as severe (crashing w/ an access violation is bad :), they still need to be planned for. [The .NET Guy]

Right, when I wrote my blurb I was thinking about the case where you are directly responsible for every endpoint implementing your interface.  The other case is when you define an interface, and then multiple companies implement your interface in a web service; in this second case, I would agree with Clemens’ rule that the namespace should be changed if a method is added, to avoid the problem Brad points out.

Clemens and Gordon on XML Web Services

Clemens and Gordon on XML Web Services

Regarding Clemens Vasters’ article on Staying sane in an XML Web Services World:

Furthermore, Clemens assumes that XML Schema is the only way to communicate a contract, but my understanding is that WSDL does not have this limitation. I’d also like to suggest that Clemens’ rule #3 is tacitly encouraging people to use .NET DataSets, which I understand to be a first-class interop-killer. And if you don’t interop, why were you doing SOAP again? [Gordon Weakliem’s Radio Weblog]

My first comment would be that, in today’s world, XML Schema is the de facto standard for expressing types in WSDL.  While you could use another type language, I haven’t seen a lot of this in real life.  So I think the article is sound in this respect.

Second, I think Clemens’ rule #3 doesn’t necessarily encourage people to use DataSets; I think it just extends his rules to the cases where someone does use a DataSet.  However, I certainly agree – DataSets are evil in public, interoperable web services.

Finally, I don’t think I completely agree with one of Clemens’ rules:

5. WSDL is immutable. It never changes. If you change a WSDL description, it becomes a new WSDL description with its own identity (namespace-URI)

and the ASP.NET corollary:

2. If you add, remove a [WebMethod] or change any of your [WebMethod]s signatures or any of the types used directly or indirectly in any of those signatures, change the namespace!

I agree with this except for the case where you’re adding a method.  Without thinking about this too awfully much, I think adding a new method would not necessarily invalidate the contract, or change the semantics of the existing methods.  In COM, we had to be careful (i.e. we didn’t do it) about adding methods, because of the problems inherent with modifying the size of the v-table on the clients.  However, with a semi-connected web services model, I don’t see how we could get into trouble adding a method.  At least not mechanically; one could make an argument that you might have clients that never knew the interface changed, but I’m not sure that alone is enough reason to rev an interface.

Where have I been?

Sorry for no posts over the last week, with absolutely no notice.  I’ve been out of town at a new client’s office, and for some reason (despite setting everything up), I couldn’t access Radio remotely.  Time to install on my laptop, I guess.

A few tidbits, which I’ll probably write more about:

1. I never realized just how cool Managed C++ is.  Well, I’m a convert now; after spending the week integrating some new .NET code with “legacy” C++ systems, I think managed C++ is the coolest thing going.  Don’t panic, I still use C# where possible…but you can’t do everything there.

2. Wireless (802.11b) is seriously cool too!  I just installed an access point in my house, and I’m starting to wonder how I got along without it.  Now if only Chipotle would install access points, I’d be the happiest camper ever.

3. Dell’s new Latitude C640 is very cool too!  This was delivered while I was out of town; a nice upgrade from my previous 8.5 pound 300 MHz portable.  My shoulder is going to thank me, I just know it…

Chick-Fil-A Cow Stolen

A 150-pound fiberglass cow has been stolen from a Chick-Fil-A billboard in Denver.  […] The cow, one of the company’s mascots urging customers to “Eat Mor Chikin,” was apparently taken during the weekend. […] Chick-Fil-A is also offering free chicken sandwiches for a year for information leading to the safe return of the cow. [Yahoo! News]

This cracks me up – probably more than most, because this billboard is less than 4 miles from my house.  The article also says “The little bandits were very innovative” – heh…they must have played tag as children.  ;-)

Fixed Digest Authentication Sample

Oops!  Justin Rudd brought the following bugs to my attention:

1. When using Opera, the cnonce value is a base-64 encoded value which may contain the ‘=’ character. The original parsing code did not correctly handle this situation.

2. Mozilla uses the entire URI (including the query string) for the uri field in the authorization header, whereas Internet Explorer does not. The original parsing code would not correctly handle the ‘=’ characters in the header.

Both are fixed now (actually the same problem in the code).  You know, it’s funny; I had just read Brad’s post about people only testing their code on IE; I guess I fell right into that one! 

Web Services Authentication with .NET – HTTP Digest Sample

I have posted an article and sample of using HTTP Digest authentication with web services, without using the built-in IIS Digest implementation and Active Directory.  Like my previous authentication sample, this one is all managed code, and will work in shared hosting environments.

I think Digest authentication has gotten a bit of a bum rap, and it’s not in widespread use.  However, it’s a standard, well-documented protocol, and it doesn’t require clear-text credential transmission, which means you don’t have to require an encrypted channel for some classes of services.  I think it’s particularly well-suited to web services, at least until WS-Security has gained widespread acceptance.  Microsoft seems to agree, as they are using Digest authentication for their MapPoint.NET service.