Sorry, you're not my type

Craig mentioned recently that he would never use the [XmlInclude] attribute because he felt it was impolite to send someone a SOAP message that used the xsi:type attribute. Kevin commented, asking why he felt that way and what toolkits might have a problem with it. I feel compelled to comment...

XML 1.0 + Namespaces do not define the notion of typed data. Everyone agrees that we need a way to assign simple types to the text value of an attribute or an element, e.g., published is a date and age is an integer. XSD adds this functionality, but goes much much further. It defines the notion of complex type, complex type derivation and complex type substitutability (at both the type and element level).

It is easy for OO developers to see a strong parallel between XSD complex types and classes, and XML instances and objects. Complex derivation by extension parallels classic OO inheritance nicely, with xsi:type providing the necessary run-time type information to indicate when a derived type is taking the place of a base type.

Appealing as this appears to be, there are two key differences between the OO and XML world that can't be ignored.

First, in modern OO systems like the CLR and Java, we always have type information at dev time and at runtime. You never have an object without also having it's type. This is not true for XSD. There is no standard way to locate and load the XSD for a given instance. Even if there were, most plumbing wouldn't do it because of the overhead. So instead, we have tools that we manually point at a schema and they consume it at dev time, but at runtime the XSD isn't there. So we don't really have XML run-time type information (unless we explicitly load it ourselves, which we rarely do); we have a projection of that information into CLR or Java types, where the mechanics of the projection are defined by our marshaler.

Second, and more important, inheritance and substitution mean very different things in OO and XSD. OO inheritance and substitution is based on behavioral polymorphism. A base type defines a behavioral contract that a consumer adheres to. If the consumer is given an instance of a more derived type, the consumer doesn't have to change. In contrast, XSD inheritance and substitution (both type and element based) provide structural polymorphism. All XML consumers analyze document structure in one way or another (stream API, tree API, XPath query, XSLT, etc.). If a consumer is written to process instances of a base type, what happens when it is given an instance of a derived type? The consumer has to be modified to check for substitution and react accordingly. That means looking for xsi:type on every element and for alternate elements in the substitution group of the element they were expecting. No one working in raw XML writes code that works that way. They write code that says “is the next element {www.example.org}person“, not “is the next element {www.example.org}person or something that a schema says is legally substitutable for that“.

Now, clearly you can make xsi:type-based substitution work with today's toolkits, so is all this just a point of theoretical purity?

No.

If you leverage this mechanism you are forcing a particular model on the person at the other end of the wire. Specifically, you are making it extremely difficult to process messages as XML directly. If they do, chances are they'll miss what you are doing. Best case, they fail. Worse case, the appear to succeed, but the results are odd because they didn't really understand what you were doing.

If you look closely at the Web services specifications, you'll see that none of them are defined in terms of XSD complex types, let alone type substitution. The SOAP 1.2 spec only mentions type relative to individual simple text values in elements or attributes like mustUnderstand and faultcode. You won't find complex type definitions in the WS-* specs either. Instead, they define things using a simpler psuedo-schema that focuses on element structure. The WS-Addressing spec does define the EndpointReference type, but the definition is by XML sample instance not XSD complex type. Yes, there are XML schemas for the WS specs, but they are explicitly non-normative. Next to anything the specs themselves, the schemas don't mean anything.

So guess what happens if you send SOAP messages with envelopes or WS-* headers where you've replaced the expected types or elements with something else? The answer is no one knows because Web service stacks are implement using XML and don't apply the same rules to themselves that they apply to the data they carry.

I don't know about you, but the thought of taking an approach to modeling the payload of my messages that is radically different than the approach taken to model the message itself makes me really nervous. So I stick much more closely to how XML itself works. That means focusing on composition and wildcards instead of inheritance and substitution. In fact, I rarely publish a schema that is not explicitly marked blockDefault=”#all” to simply disable type and element substitution altogether.


Posted Jul 12 2004, 07:48 PM by tim-ewald

Comments

Anonymous wrote re: Sorry, you're not my type
on 07-22-2004 6:19 PM
First, in modern OO systems like the CLR and Java

...I didn't realize that the CLR is a modern OO System. I thought that the CLR is the common language runtime, which really would be the same the java runtime? What's the difference?
Anonymous wrote re: Sorry, you're not my type
on 07-23-2004 2:46 PM
You guys crack me up, you make a living on this babble? First of all XML is a notation. It is a launguage. Second of all it is only a way to describe inforation and structure. You define a Mark-up launguage and then you immeadiatly are uncomfortable with What it doesn't do.. Okay it's not OO. It doesn't map to Objects. Who Cares.. Re-think what you are REALLY Trying to do, by sending types over the wire. Get over it dude! Just kidding, nice little write up. ;)
Tim wrote re: Sorry, you're not my type
on 07-23-2004 3:07 PM
You're misinterpreting my post. I'm not uncomfortable with what XML doesn't do. In fact I love it. My point was warning people off the OO-centric aspects of XSD, which is a bad place to go.
At Your Service wrote I refuse to let the angle brackets fall where they may!
on 07-23-2004 3:36 PM
Anonymous wrote re: Sorry, you're not my type
on 07-23-2004 3:51 PM
Tim,
I know, I was just kidding you.. I agree totally! Believe me you know 100x more about this than me. I am just a simple computer geek. But I really think if you are going to go S.O. using messaging over the wire, you should have the most simple COMMAND line message structure. How does one pass typed data over the wire? Like, you want to send me a typed field say a Published Date. How do I know if you are sending me a Date, or a Derived Type? I don't. But really it is your responsibility to send me what I am expecting as a service for example. right? Okay, but now you are forcing me to have to try and morph your goo down to what I want. this is your point? no. Okay so, again how do we send types over?

Just read an old quote from the Don Box:

"When we started working on SOAP in 1998, the goal was to get away from this model of integration by code injection that distributed object technology had embraced. Instead, we wanted an integration model that made as few possible assumptions about the other side of the wire, especially about the technology used to build the other side of the wire. We've come to call this style of integration protocol-based integration or service-orientation."

Okay Nicely said DB. Now I contend that If I spit in the face of your service, that I deserve to get smacked Back! So I don't get what I am expecting back from the service. That is my side of the contract. Now on your side, it is your job to protect your internal interest as a service. Period. Just like if I call a method by sending it a null reference, I get an exception. And it's that cut and dry. Am I just talking out my arse here? I am really not experienced in this area.

So I agree, there should be no polymorphing by osmosis here. The real difference is in say an actual compiler that sniffs my type and shave my type down to what your method is asking, and if it can't it smacks me at compile time. That is what is missing in this Over the wire Message story, you guys been working on..

At Your Service wrote I refuse to let the angle brackets fall where they may!
on 07-23-2004 3:53 PM
Harry Pierson's DevHawk Weblog wrote New Architect Bloggers
on 07-23-2004 4:07 PM
Tim wrote re: Sorry, you're not my type
on 07-23-2004 4:07 PM
I don't want people to give up typed XML, just polymorphic typed XML. When I design the schema for a Web service (or anything else) I mark it blockDefault="#all" to indicate that both type and element substitution are disallowed. That doesn't stop me from saying that the PublishedDate element is a date. More importantly, it guarantees that you, as a consumer, know it's a PublishedDate and not something derived from that. That makes it a lot easier for you to implement a correct system using raw XML if you desire.
ccBoy wrote New Architect Bloggers
on 07-24-2004 1:51 AM
TrackBack From:http://www.cnblogs.com/ccboy/archive/2004/07/24/27100.aspx
Mike Kozlowski wrote re: Sorry, you're not my type
on 07-25-2004 5:45 PM
It seems to me that the problem is a schema language that leads you to do the wrong thing. I'm not particularly familiar with WXS (as I've never needed it yet for anything) so think of schemas in Relax NG terms, and from that perspective, the idea that anyone would try to model document schemas as objects is just plain bizarre.
Jon Fancey wrote re: Sorry, you're not my type
on 07-26-2004 2:46 AM
Surely, if you are exchanging typed messages with one another then you can do this because you ARE sharing something. That common type system - XML schema support. It's only if you extend that you have to share *more*. Is this a problem? Well, it is if you anticipate exchanging messages with complete strangers. But if you're not, and for many non-trivial purposes, most aren't, then I don't see it as a technical problem. I fully agree with the view that the less you have to *share* (read exchange) the better, in distributed scenarios - this IS a technical problem. So I'm not sure the correct advice is, *never* use this extension stuff, more that, just make sure you know what you're doing and keep your eyes wide open when you look at the actual problem you're trying to solve.

The problem with the whole webservices stack story right now is that just 'cos it's there doesn't mean you should use it. Best practice is only slowly emerging...
At Your Service wrote Comments about my post on XSD and type substitution...
on 07-26-2004 5:03 AM
Jim Murphy - Mindreef wrote re: Sorry, you're not my type
on 07-29-2004 12:48 PM
Hmmmm - interesting point, Jon. So if the universe of subtypes is know a priori why use element or type substitution? why not use xs:choice?
Tim wrote re: Sorry, you're not my type
on 07-29-2004 1:12 PM
Ah, Jim, you're a man after my own heart. Put another way, why not just use XML the way it's designed, as opposed to playing fancy XSD games? :-)
Jon Fancey wrote re: Sorry, you're not my type
on 08-05-2004 11:20 PM
Absolutely!

Add a Comment

(required)  
(optional)
(required)  
Remember Me?