<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.pluralsight.com/community/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>XML Nation</title><link>http://www.pluralsight.com/community/blogs/tewald/default.aspx</link><description>Fight the power</description><dc:language>en</dc:language><generator>CommunityServer 2008 SP1 (Build: 30619.63)</generator><item><title>ROA vs GET/POST</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2007/10/19/48805.aspx</link><pubDate>Fri, 19 Oct 2007 16:51:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:48805</guid><dc:creator>tim-ewald</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=48805</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2007/10/19/48805.aspx#comments</comments><description>&lt;P&gt;Bill deHora has a great &lt;A href="http://www.dehora.net/journal/2007/10/my_bowlegged_master.html"&gt;response&lt;/A&gt; to &lt;A href="http://pluralsight.com/blogs/tewald/archive/2007/05/10/47273.aspx"&gt;one of my (somewhat) recent REST posts&lt;/A&gt;. The timing is perfect, because I've been thinking a lot about what I said in those posts. I've also just finished reading the &lt;A href="http://www.amazon.com/gp/product/0596529260/ref=s9_asin_image_1/002-2717615-6440852?pf_rd_m=ATVPDKIKX0DER&amp;amp;pf_rd_s=center-2&amp;amp;pf_rd_r=01JB8RB4ZWGKNKBM6AHB&amp;amp;pf_rd_t=101&amp;amp;pf_rd_p=278240301&amp;amp;pf_rd_i=507846"&gt;RESTful Web Services&lt;/A&gt; book, which is the most useful technical book I've read in a while, and have been thinking a lot about what it says too (and talking about it with Craig). I've been mulling over a post for a couple of days, and Bill's post is the impetus I needed to share what I've been thinking.&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P&gt;In RESTful Web Services, the authors define and argue the merits of Resource Oriented Architecture. ROA maps directly to the REST-as-CRUD model for thinking of the world, where interaction with your system is modeled entirely in terms of create, read, update and delete operations against data resources. For data-centric services, like the del.icio.us service that they refactor in the book, this model makes a ton of sense.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P&gt;But what if your problem domain is more focused on processes than data? As the authors show with their proposal for modeling transactions, you can map any process to ROA with the following steps (or ones like them):&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;UL type=disc&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;PUT/POST to create a new process resource&lt;o:p&gt;&lt;/o:p&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;PUT to update that resource to include the data it needs&lt;o:p&gt;&lt;/o:p&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;PUT to execute that process&lt;o:p&gt;&lt;/o:p&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;GET to fetch the result&lt;o:p&gt;&lt;/o:p&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This maps any process to a set of resources. From this perspective, my argument that HTTP is all about POST and everything else is an optimization or unnecessary doesn&amp;#8217;t make sense.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P&gt;So could I model all processes the ROA way? Undoubtedly yes. But, what&amp;#8217;s the value of this over just doing a POST with the data I want to process and getting the result back? It&amp;#8217;s much easier to implement that because I don&amp;#8217;t need the build-up of the process resource to span multiple stateless requests. I don&amp;#8217;t ask this rhetorically, I really want to understand why people think this approach to modeling processes is better. (This is especially true if core bits of network infrastructure don&amp;#8217;t support PUT/DELETE and you end up having to tunnel them through POST anyway.)&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P&gt;Maybe the process perspective is just the wrong way to think about the world, but it&amp;#8217;s where a lot of people&amp;#8217;s heads are at, including almost all the SOA/WS folks out there. In looking at my own system, I see one interface that is obviously data-centric and fits easily into the ROA model. Another interface is very process oriented. Right now we&amp;#8217;re doing it with GET for read and POST for write, and it works and people get it. While I can see how to map it into the ROA model, I&amp;#8217;m still unclear on how it helps.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P&gt;So, to summarize, Bill is right: you shouldn&amp;#8217;t follow what I said in that earlier post. (I always reserve the right to get smarter, and I&amp;#8217;m using that now.) I&amp;#8217;m still debating between the full ROA vs. GET for read and POST for write (again, especially if I have to tunnel through POST anyway), I really need to build some more stuff and see how it plays out.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=48805" width="1" height="1"&gt;</description></item><item><title>Don asked for input...</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2007/08/26/48298.aspx</link><pubDate>Sun, 26 Aug 2007 16:17:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:48298</guid><dc:creator>tim-ewald</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=48298</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2007/08/26/48298.aspx#comments</comments><description>&lt;P&gt;I haven't been reading or writing much lately - too heads down getting to 1.0. But I did happen across Don's &lt;A href="http://pluralsight.com/blogs/dbox/archive/2007/08/15/48232.aspx"&gt;recent post&lt;/A&gt; about retiring the four tenets of SOA and asking for input on what we'd like to write when we implement services. Let me take these topics in order. First, the four tenets of SOA...&lt;/P&gt;
&lt;P&gt;What people are trying to build are loosely-coupled systems where pieces can be changed without breaking other pieces. I've built a couple of systems that meet that goal to a reasonable degree, so I don't think it's unreasonable for me to say that it's possible but hard and it takes a long time. In fact, it's just like building reusable components, which is also possible, hard and takes a long time. It isn't clear to me that many organizations are actually prepared to put in the work that loose-coupling really requires. What is clear to me is that the 4 tenets and the current tools aren't going to get them there. The only thing they really do is distract Capital-A-architects, which isn't a bad thing.&lt;/P&gt;
&lt;P&gt;Which gets me to the second topic, what does the code I want to write look like. Here's my current thinking...&lt;/P&gt;
&lt;P&gt;There are 4 essential distributed technologies: sockets, message queuing, RPC, and REST (in the distributed state machine sense I was writing about a couple months ago). There is a place for each in my current system. We use sockets to support certain industry and legacy protocols, both TCP and UDP, including multicast. We're looking at using message queuing for some ancillary processing off the main line of execution. We're using RPC to talk to SQL Server - either TDS, which is essentially RPC with streams, or SOAP via WCF, which is also essentially RPC despite what the proponents of mass customization exhort you to, in cases where a physical deployment separates our client from our database and the IT guys don't want to open 1433. For loosely-coupled cross-component integration we use REST.&lt;/P&gt;
&lt;P&gt;I don't care that there are different APIs for all these technologies. In fact, I think it's a good thing because (a) I get an API tailored for the technology I'm using which (b) makes the differences between them clear. The only API that is lacking in .NET, IMO, is the REST one. If you aren't doing pages, ASP.NET leaves you hanging with IHttpHandler. Similarly, HttpListener isn't much of an API. Yes, I could put the new WCF REST bits on top, but I haven't, for several reasons. we needed a solution before they were available, so&amp;nbsp;we already have a UriTemplate-based dispatcher of my own. We don't want to change .NET libraries at this point in the project, and can't move to a beta anyway. And finally, I'm not sure I want to build on a layer designed to factor HTTP in on top of a layer that was designed to factor it out.&lt;/P&gt;
&lt;P&gt;The lack of a strong REST API is problematic because REST is a much better alternative for loose-coupling than RPC is. So, what do I want for an API? Easy: I want a UriTemplate matching layer (with a back-door for arbitrary regex's) that works on ASP.NET or HttpListener, abstracting away the differences between their respective context/request/response objects (which is just annoying). And I want a text-templating engine for output, a la NVelocity, with editor support. I'm close to building my own, since I already have the first half, with NVelocity, but haven't had time yet. (Yes, I've looked at monorail, but it feels like more than I want and I don't think it integrates with HttpListener.)&lt;/P&gt;
&lt;P&gt;I'd like all that to run on top of 2.0 if possible, or at least in a kit that runs on XP and 2003, even if it requires 3.0 or 3.5. And I'd like it in the next 6 months or so (which I know is a pipe dream). The lack of this interfaces is a big part of my interest in Rails.&lt;/P&gt;
&lt;P&gt;As to an example based on TransferMoney, here's what I'd do...&lt;/P&gt;
&lt;P&gt;Design an idempotent implementation with a unique request id that can be saved on a client before initiating the request, used by a client in the case of failure to ask if the operation was processed (maybe by looking through a list of the operations processed in the last 24 hours), and used by the server to avoid processing the same request twice. (I'd make this part of the application logic instead of the transport protocol because reliability of the latter doesn't mean I can' t crash between getting a message and executing logic based on it, unless I go all transactional messaging, which introduces other issues.)&lt;/P&gt;
&lt;P&gt;I would map out the state machines for the client, the server and the protocol between them. I would map the protocol itself to a set of URLs, as per my recent posts on REST. I would implement the endpoints by mapping URLs to methods using UriTemplates, parse the inbound data using whatever felt right and emit a response using a text templating engine.&lt;/P&gt;
&lt;P&gt;I'd test it with the browser. I'd document it in prose, and maybe with an XSD for reference or to generate code if desired.&lt;/P&gt;
&lt;P&gt;Don't know if that's concrete enough. It echoes what we're doing in our system now, which works great.&lt;/P&gt;
&lt;P&gt;If the question was what do I want to see as a SOAP API, I don't have any issue with the [WebMethod]-esque style that WCF&amp;nbsp;and every other stack uses. SOAP/WS-* turned out to be RPC/CORBA and the API is fine. That isn't as negative a statement as you might think.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=48298" width="1" height="1"&gt;</description></item><item><title>What's in a name?</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2007/05/10/47273.aspx</link><pubDate>Thu, 10 May 2007 17:06:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:47273</guid><dc:creator>tim-ewald</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=47273</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2007/05/10/47273.aspx#comments</comments><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;My recent posts are my attempt to describe how I think about the Web and how it can be leveraged to integrate systems independent of the browser. I got a &lt;STRONG&gt;ton&lt;/STRONG&gt; of feedback in comments and email, which was all great. I&amp;#8217;ve been away for a bit, so I thought it would be good to come back and summarize, and to ask a question about what to call the model I&amp;#8217;ve adopted. Specifically, some worry that the term REST means too many things to too many people to have any real meaning at all. But before I get to that, let me summarize and respond to some of the key points people made. &lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Most of the feedback I got can be divided into a couple of bins...&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;First, that it&amp;#8217;s just RPC. That&amp;#8217;s wrong for all the reasons I listed in my last 4 posts.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Second, it&amp;#8217;s not RPC, so it isn&amp;#8217;t appropriate beyond browsing a hypertext graph of multimedia content. The first half is right. I strongly believe the second half is wrong, but we don&amp;#8217;t have enough experience applying the model in other systems to say concretely. We need to get that experience.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Third, and most interesting, what you describe isn&amp;#8217;t REST, for a range of reasons. Some of this was because I wasn&amp;#8217;t crisp in defining the difference between managing system state, session state, and transitions between nodes in a protocol state machine. Clients make HTTP requests to move through a protocol state machine. This is completely unrelated to changing system state or to maintaining session state. Specifically, a GET is a move between nodes (or states) in the protocol, but does not (or should not) affect system state. I adopted the term &amp;#8220;node&amp;#8221; here to describe moving between states in the protocol state machine. Is that clearer?&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Some felt I didn&amp;#8217;t conform to REST because I didn&amp;#8217;t include the notion of changes over time. Specifically, I said that each state in a protocol state machine has a URI, which I think is true. Each time the client enters this state, they get a representation of it. That representation may change over time. That doesn&amp;#8217;t mean that each state in the protocol doesn&amp;#8217;t have a unique URI, it means that each representation does not (unless you mix perma-links into the protocol). &lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The most important feedback worried about the fact that the Web isn&amp;#8217;t really RESTian or that my model doesn&amp;#8217;t align very well with the HTTP spec, which focuses on CRUD operations on entities. Let me address those concerns.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The Web does not fully conform to Fielding&amp;#8217;s paper, but the reality is that the Web is RESTful enough. An implementation is never as pure as an idea (Look deeply the SOAP header processing model and the not-so-independent WS-* specs for another great example.). Yes, the modern Web uses cookies extensively, which don&amp;#8217;t conform to Fielding&amp;#8217;s ideas, but are extremely useful. More importantly, they do not sacrifice the notion of a stateless server, as long as there is a shared backend store. We could debate the merits of a stateless client vs. a stateless server, but the latter is how the Web really works, and pragmatically, that&amp;#8217;s what I&amp;#8217;m after, whether it conforms to Fielding or not. &lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;About the model I&amp;#8217;ve adopted not aligning with the HTTP spec, I disagree. The spec is written substantially in terms of CRUD operations on resources. The goal of the early Web was essentially distributed content publishing, the ancestor of the Wiki. The HTTP spec reflects that. We&amp;#8217;ve moved well passed that problem domain to all sorts of other things, e.g., shopping at Amazon. It&amp;#8217;s easy to think of the shopping process in terms of a protocol state machine. It&amp;#8217;s harder to think of the content management problem that way, but you can if you try. In that problem space, the protocol state machine and the CRUD operations on entities converge into one model &amp;#8211; in content management, the CRUD operations on the entities &lt;STRONG&gt;are&lt;/STRONG&gt; the transitions in the protocol state machine.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;I&amp;#8217;ve been very careful in my last several posts not to get hung up on which HTTP methods are being used to transition between states. The HTTP spec positions the four main methods as equals, but I don&amp;#8217;t look at it that way. POST is the core method. GET is an optimization that enables caching and, more importantly, makes it possible to bookmark protocol states as a single text string. PUT and DELETE made it in because of how the Web was first conceived. If it had started with the Amazon shopping cart, those verbs might not have been there. They might have been in an extension protocol, like WebDAV, but it didn&amp;#8217;t happen that way. (Hopefully that isn&amp;#8217;t too inflammatory.) I back up this position with the observation that while we encounter GET and POST all the time, PUT and DELETE are very rare. (Maybe APP will change that, but it hasn&amp;#8217;t happened yet, and falls in the content management problem space for which those special verbs were defined anyway.)&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;But all of that is really moot. I don&amp;#8217;t want to get lost in discussions or architectural styles, whether or the Web really conforms to Fielding (my answer is it conforms enough), whether REST and HTTP align, whether it is possible to be RESTian at all, the meaning of PUT and DELETE, or other distractions. I want to focus on digging into HTTP-based distributed state machines (a term I got from Sam) that leverage the pragmatic solutions for scalability, reliability, and security that we&amp;#8217;ve developed on the Web.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;So given all that, is REST the best term to use for this, or is there something better?&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=47273" width="1" height="1"&gt;</description></item><item><title>Three reasons that REST is not RPC</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2007/04/28/47067.aspx</link><pubDate>Sat, 28 Apr 2007 23:01:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:47067</guid><dc:creator>tim-ewald</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=47067</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2007/04/28/47067.aspx#comments</comments><description>&lt;P&gt;I've gotten several comments&amp;nbsp;saying that, at the end of the day, REST is just RPC. That's wrong, for at least 3 very reasons:&lt;/P&gt;
&lt;P&gt;1) Each unique state in your protocol state machine has its own URI. That's different from an RPC endpoint that maintains a black-boxed state machine at a single endpoint. Being able to do state transition processing at disparate locations is hugely powerful. Watch the URLs you are navigating through as you browse, shop and checkout at Amazon. A single process can span machines offering differing levels of scalability, reliability and security.&lt;/P&gt;
&lt;P&gt;RPC doesn't do that. You could conceivably build an RPC system that did do that, but if that happens it is a very rare occurence indeed. The more likely solution would be to have multiple RPC interfaces to the different machines involved in the process and then tie their protocols together. The application in the middle would have to understand how to mix the two protocols, passing data from one into the other, and back the other way. Yes, you can make it work, but it bakes a lot of protocol detail into the application mixing the calls, creating a much more complex solution.&lt;/P&gt;
&lt;P&gt;2) With transition URIs embedded in the representations of states, it's easier to transition between states in the protocol. All of the URIs are accessed the same way, there is no separate interface per endpoint because the each endpoint represents the transition to an&amp;nbsp;individual states, not all of the transitions required by a protocol. Again, technically this is doable with RPC, but nobody does it this way and solutions are more complex as a result.&lt;/P&gt;
&lt;P&gt;3) The messages aren't interpreted as serialized call-stacks. The purpose of RPC is to copy a stack frame from one process to another, where it exists for the duration of a method call. That makes RPC very natural to anyone used to invoking a method, but it also makes it very hard to alter one side of the system without altering the other. While HTTP-based systems still use request/response messages, they aren't call-stacks. The fact that WS tools want to treat them that way is one of the reasons they have so much trouble handling large binary data, e.g., JPEG.&lt;/P&gt;
&lt;P&gt;None of this is to say that RPC isn't useful. A couple people have mentioned callbacks to clients behind NAT based firewalls, a problem that RPC based on WCF duplex channels are very good at solving (protocols like XMPP and plain old TCP work well too). My system uses both RPC and REST. But it's a mistake to say that REST is RPC just because HTTP is request/response, we often use XML to represent state, and there are tools to map XML to and from callstacks. I made that mistake for a long time, until I realized what REST really is.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=47067" width="1" height="1"&gt;</description></item><item><title>On programming models...</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2007/04/27/47032.aspx</link><pubDate>Fri, 27 Apr 2007 19:04:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:47032</guid><dc:creator>tim-ewald</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=47032</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2007/04/27/47032.aspx#comments</comments><description>&lt;P&gt;Ittay &lt;A href="http://pluralsight.com/blogs/tewald/archive/2007/04/26/46984.aspx#47022"&gt;commented&lt;/A&gt; on my REST &lt;A href="http://pluralsight.com/blogs/tewald/archive/2007/04/26/46984.aspx"&gt;post&lt;/A&gt;:&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;the thing is, when you write software, you use an RPC model. what bothers me about REST is that it is not only an API. it enforces you to change your programming model. &lt;BR&gt;&lt;BR&gt;that is not to say i don't like it. i do, for its simplicity and self documentation (e.g., provide all moves as links), but there is a price you pay. &lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;When you write software, you use a programming model that works. And sometimes you have to change models. We changed them for the Web: we moved to the notion of pages. It wasn't RPC, it wasn't even objects (at least from most developers perspectives originally). But it was simple and did what it was supposed to do. I've done RPC, CORBA, DCOM, Remoting, RMI, and Web services. All of those technologies have their place. But they all struggle in a loosely-coupled, massively distributed world. I'll happily change my programming model to solve that.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=47032" width="1" height="1"&gt;</description></item><item><title>An example might help...</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2007/04/27/47031.aspx</link><pubDate>Fri, 27 Apr 2007 18:56:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:47031</guid><dc:creator>tim-ewald</dc:creator><slash:comments>13</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=47031</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2007/04/27/47031.aspx#comments</comments><description>&lt;P&gt;I got a lot of great comments on last nights post, including a couple about REST being no different from xml-based RPC. I used to think so too, which is why my recent epiphany was so eye opening.&lt;/P&gt;
&lt;P&gt;Consider a protocol for finding and reserving a flight between two cities. The client is in one of these states:&lt;/P&gt;
&lt;P&gt;&amp;lt;ready&amp;gt;&lt;BR&gt;- searched&lt;BR&gt;- retrieved details&lt;BR&gt;- reserved&lt;/P&gt;
&lt;P&gt;These states map to URIs:&lt;/P&gt;
&lt;P&gt;&amp;lt;none&amp;gt;&lt;BR&gt;- http://quuxTravel.com/searched&lt;BR&gt;- ??? depends on previous state&lt;BR&gt;- ??? depends on previous state&lt;BR&gt;&lt;BR&gt;A client begins by navigating to the &lt;EM&gt;searched&lt;/EM&gt; state by GETting http://quuxTravel.com/searched?src=London&amp;amp;dest=NYC. The client gets back some XML like this:&lt;/P&gt;
&lt;P&gt;&amp;lt;itineraries&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;itinerary src=&amp;#8220;London&amp;#8220; dest=&amp;#8220;NYC&amp;#8220; price=&amp;#8220;400.03&amp;#8220;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;getDetails uri=&amp;#8220;http://quuxTravel.com/details?itinerary=402&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;reserve uri=&amp;#8220;http://reservations.bookingsunlimited.com/quuxTravel?itinerary=402&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/itinerary&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;itinerary src=&amp;#8220;London&amp;#8220; dest=&amp;#8220;NYC&amp;#8220; price=&amp;#8220;109.88&amp;#8220;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;getDetails uri=&amp;#8220;http://quuxTravel.com/details?itinerary=219&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;reserve uri=&amp;#8220;http://reservations.bookingsunlimited.com/quuxTravel?itinerary=219&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/itinerary&amp;gt;&lt;BR&gt;&amp;lt;/itineraries&amp;gt;&lt;/P&gt;
&lt;P&gt;The client is now in the searched state. It scans the list of itineraries to find the one with the lowest price. If the client wanted some other criteria that isn't surfaced in this state, e.g., total flight time, it could transition to the &lt;EM&gt;retrieved details&lt;/EM&gt; state by GETting the URI stored in the itinerary's getDetails/@uri attribute. It would then return to the searched state (either by an explicit&amp;nbsp;back-link or a history a la' the browser). The system would return an XML representation of that state that contained flight info.&lt;/P&gt;
&lt;P&gt;When the client has chosen a flight, it transitions to the &lt;EM&gt;reserved&lt;/EM&gt; state by POSTing to the URI stored in the itinerary's reserve/@uri attribute. It gets back an XML document confirming the reservation. At this point the protocol is complete. The client can begin again if desired, or go do something else.&lt;/P&gt;
&lt;P&gt;Now, why is this different from RPC? Imagine the following interface for implementing this same protocol:&lt;/P&gt;
&lt;P&gt;interface IFlightSystem&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Itineraries Search(string src, string dest);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Details GetDetails(int itineraryId);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Confirmation Reserve(itineraryId);&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;This interface exposes the same protocol, with more or less the same requirements on the client to know what the data being sent and received means. The difference is that in this case, the client is talking to one endpoint and mapping request/response payloads to call stacks. In the previous case neither of those things were true.&lt;/P&gt;
&lt;P&gt;The REST model opens the door for the protocol to be implemented across different endpoints. This is useful for scalability, partitioning and data-directed routing, integration with external systems (note that the transition to the &lt;EM&gt;reserved&lt;/EM&gt; state uses a URI at a partner company). In other word, it's actually a web of endpoints. Further, those URIs are dynamically constructed, so you can change them based on user, time of day, the data they're interested in, locale they're from, state of your data center, or whatever. That is hugely powerful. Because the documents being sent around are not mapped to call stacks, and may not even be mapped to objects, it's easier to stream data, add extra stuff over time, etc.&lt;/P&gt;
&lt;P&gt;In one of his &lt;A href="http://pluralsight.com/blogs/tewald/archive/2007/04/26/46984.aspx#47006"&gt;comments&lt;/A&gt;, Ittay asked what the REST model for the a method &amp;#8220;string Foo(string, int, bool)&amp;#8221; would be. In &lt;A href="http://pluralsight.com/blogs/tewald/archive/2007/04/26/46984.aspx#47025"&gt;response&lt;/A&gt;, I described a simple protocol with one state, &amp;#8220;FooInvoked&amp;#8221;. To get to that state, you'd access a URI for /foo, passing a string, int and bool as query string parameters or in the request body. You'd get back a result state that contained a string. He &lt;A href="http://pluralsight.com/blogs/tewald/archive/2007/04/26/46984.aspx#47027"&gt;countered&lt;/A&gt;&amp;nbsp;that that felt just like a function call, which isn't surprising because that's where we started. The key, for me, is to look at problems not from the perspective of methods, as Ittay did, or entities, as Joe &lt;A href="http://bitworking.org/news/How_to_create_a_REST_Protocol"&gt;describes&lt;/A&gt;, but as states and the transitions between them. Then it really starts to make sense. And the power of it is real.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=47031" width="1" height="1"&gt;</description></item><item><title>I finally get REST. Wow.</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2007/04/26/46984.aspx</link><pubDate>Thu, 26 Apr 2007 18:39:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:46984</guid><dc:creator>tim-ewald</dc:creator><slash:comments>70</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=46984</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2007/04/26/46984.aspx#comments</comments><description>&lt;P&gt;Yeah, I'm alive. &lt;EM&gt;And&lt;/EM&gt; I remember the password to my blog. I've been away for a bit, working on something very cool involving the TV. If all goes well, you'll hear about it in a big way. Anyway, I'm still having a ball out here in reality. Building something real has a way of focusing your decisions about technology. My app is a distributed system, some of which runs in a cable plant head-end or telco office (whatever's on the other end of the wire in your living room), and some of which runs elsewhere. We also connect to some things on the Web. These connections have to be extremely flexible and the bar to adoption has to be low. The thing I finally realized (some of you will say &amp;#8220;Duh!&amp;#8221;) is that Web services are not a good way to do this.&lt;/P&gt;
&lt;P&gt;It's depressing to think that SOAP started just about 10 years ago and that now that everything is said and done, we built RPC again. I know SOAP is really an XML messaging protocol, you can do oneway async stuff, etc, etc, but let's face it. The tools make the technology and the tools (and the examples and the advice you get) point at RPC. And we know what the problems with RPC are. If you want to build something that is genuinely loosely-coupled, RPC is a pretty hard path to take.&lt;/P&gt;
&lt;P&gt;That realization would have gotten me down if not for the fact that something else jazzed me up an hour or so later. I was in the process of considering the alternatives when I finally understood REST. And wow, it was eye-opening. REST is often positioned as CRUD operations against entities identified by URIs. Then it is dismissed as to simplistic to be useful. You can't build with just CRUD, the reasoning goes, just think about why we write sprocs. I've been down that path any number of times and always ended up in the same place. But I had it all wrong.&lt;/P&gt;
&lt;P&gt;I skimmed Fielding's thesis a while back, but it wasn't until I read &lt;A href="http://www.intertwingly.net/"&gt;Sam Ruby's recent posts&lt;/A&gt; that it really sank in. Here's what I came to understand. Every communication protocol has a state machine. For some protocols they are very simple, for others they are more complex. When you implement a protocol via RPC, you build methods that modify the state of the communication. That state is maintained as a black box at the endpoint. Because the protocol state is hidden, it is easy to get things wrong. For instance, you might call Process before calling Init. People have been looking for ways to avoid these problems by annotating interface type information for a long time, but I'm not aware of any mainstream solutions. The fact that the state of the protocol is encapsulated behind method invocations that modify that state in non-obvious ways also makes versioning interesting.&lt;/P&gt;
&lt;P&gt;The essence of REST is to make the states of the protocol explicit and addressible by URIs. The current state of the protocol state machine is represented by the URI you just operated on and the state representation you retrieved. You change state by operating on the URI of the state you're moving to, making that your new state. A state's representation includes the links (arcs in the graph) to the other states that you can move to from the current state. This is exactly how browser based apps work, and there is no reason that your app's protocol can't work that way too. (The &lt;A href="http://www.ietf.org/internet-drafts/draft-ietf-atompub-protocol-14.txt"&gt;ATOM Publishing protocol&lt;/A&gt; is the canonical example, though its easy to think that its about entities, not a state machine.)&lt;/P&gt;
&lt;P&gt;The &amp;#8220;state machine as node graph traversed via URI&amp;#8221; view of the world has really interesting implications for being able to suspend and resume a protocol. Because links to other states are embedded in a state's representation there are interesting ways to solve dynamic load-balancing, data-directed-routing, versioning and other problems using normal Web infrastructure. And because it's HTTP based, you get all the features that protocol supplies, including streaming and support for non-XML MIME types (a huge concern when you're doing TV stuff). The one thing that's really missing here is a simple framework for implementing a URI graph on top of an HTTP handler (similar to what &lt;A href="http://weblogs.java.net/blog/mhadley/"&gt;Marc's been working on for Java&lt;/A&gt;). I'm building my own now.&lt;/P&gt;
&lt;P&gt;The thing I love about this model is that, as Sam says, it is &lt;EM&gt;of&lt;/EM&gt; the Web, not &lt;EM&gt;over &lt;/EM&gt;the Web&lt;EM&gt;.&lt;/EM&gt; That doesn't mean I'll use it for everything. I use TDS to get to SQL Server. I use WCF for RPC-style communication between distributed components within major systems. I'll use this model when I cross major system boundaries, especially when I don't own both sides. I'll let you know how it turns out.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=46984" width="1" height="1"&gt;</description></item><item><title>Are Excel Services the way to bring developers and business people together?</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2006/06/14/27637.aspx</link><pubDate>Wed, 14 Jun 2006 10:58:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:27637</guid><dc:creator>tim-ewald</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=27637</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2006/06/14/27637.aspx#comments</comments><description>I heard about &lt;A href="http://msdn2.microsoft.com/en-us/ms582023.aspx"&gt;Excel Services&lt;/A&gt; a while ago, but hadn't had any time to look at them even briefly until now. Basically, it's a server-side system that lets you access data and calculations in Excel spreadsheets via Web services. Think about how much business data and calculation is done with Excel. Now imagine being able to leverage the directly. Want to change the algorithm you use to compute some key financial data? Let the analyst modify the spreadsheet and copy the update to your server and you're done. Now *this* is the way to align technology and business. Of course, that assumes it all actually works well - I haven't done anything yet. But still, it has *tons* of potential. Very cool idea, definitely something to spend more time with.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=27637" width="1" height="1"&gt;</description></item><item><title>MSDN Content Web Services online...</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2006/06/12/27291.aspx</link><pubDate>Mon, 12 Jun 2006 16:58:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:27291</guid><dc:creator>tim-ewald</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=27291</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2006/06/12/27291.aspx#comments</comments><description>&lt;P&gt;One of the last things I did before leaving the &lt;A title=MSDN href="http://msdn.com"&gt;MSDN&lt;/A&gt; team was to prototype a Web service for retrieving content programmatically. It's been a while since then, but a production version &lt;A href="http://services.msdn.microsoft.com/ContentServices/ContentService.asmx"&gt;is now live&lt;/A&gt;. Craig provides an excellent introduction &lt;A href="http://pluralsight.com/blogs/craig/archive/2006/06/12/27273.aspx"&gt;here&lt;/A&gt;. The prototype client we always talked about was msdnman - a command line tool like the Unix man command. Craig was the lucky one - he got &lt;A href="http://pluralsight.com/blogs/craig/archive/2006/06/12/27288.aspx"&gt;to build it&lt;/A&gt;. It will be interesting to see what people do with these services. Off the top of my head, I can imagine including actual docs in a technology site, integrating with tools (a la' Reflector), and building a team level doc repository on TFS that allows you to annotate, add your own docs, etc. Anyway, congrats to the MTPS team for a job well done!&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=27291" width="1" height="1"&gt;</description></item><item><title>Two articles, one good and one bad...</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2006/05/19/24507.aspx</link><pubDate>Fri, 19 May 2006 18:30:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:24507</guid><dc:creator>tim-ewald</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=24507</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2006/05/19/24507.aspx#comments</comments><description>&lt;P&gt;I ran into two Web service related articles recently. One really resonated with me: &lt;A href="http://www.architecturejournal.net/2006/issue7/F6_Enable/default.aspx"&gt;Enable the Service Oriented Enterprise&lt;/A&gt;, in the MS Architecture&amp;nbsp;Journal.&amp;nbsp;It presents the Enterprise Service Orientation Maturity Model, or ESOMM. Okay, I know what you're thinking: eeeeeeeewwww, a maturity model! But it's a lot more interesting and useful than you think (and they distance themselves from that other MM in a sidebar). Lots of developers and some architects think about service orientation in terms of the famous four tenets. They are good guiding principles and very useful, but not what a lot of people mean when they talk about SOA, all caps. Sure, there's a lot of hype around SOA, but there is a real point there too. Many companies are trying to redesign their software infrastructure into a portfolio of coarse-grained, reusable services. To do that successfully, you have go way past the four tenets for individual services and think about how you're going to organize the whole thing. I spent a lot of time thinking about that problem when I was at &lt;A href="http://www.mindreef.com"&gt;Mindreef&lt;/A&gt;. This article really summarized a lot of what I'd thought about, and a bunch of stuff I hadn't, in a nice, easy to understand way. If you work at a company doing &amp;#8220;big SOA&amp;#8221;, look at ESOMM.&lt;/P&gt;
&lt;P&gt;The other article, &lt;A href="http://csdl2.computer.org/persagen/DLAbsToc.jsp?resourcePath=/dl/mags/ic/&amp;amp;toc=comp/mags/ic/2006/03/w3toc.xml&amp;amp;DOI=10.1109/MIC.2006.45"&gt;Avoid XML Schema Wildcards For Web Services Interfaces&lt;/A&gt;, appeared in Internet Computing, but can't be downloaded without purchasing (which is pretty crumby, guys!). I got my copy forwarded by an interested reader who wanted my opinion on the position it took. I agree with the beginning of the article, which was disagreeing with the &lt;A href="http://www.idealliance.org/proceedings/xml04/papers/248/Extending-VersioningXML.html"&gt;schema techniques&lt;/A&gt; described by Dave Orchard (and reiterated with slight variation by Dare) &lt;A href="http://www.w3.org/2001/tag/doc/versioning.html"&gt;that were embraced by the W3C TAG&lt;/A&gt;. This approach is just too complicated in practice. The second part&amp;nbsp;of the article described a versioning model that supported backward compatibility (old sender, new receiver) but did not address forward compatibility (new sender, old receiver). The problem with this one-way compatibility is that it just doesn't work. Imagine a typical request/response message exchange between an old client and&amp;nbsp;a new service. The request message must support backward compatibility so that the old sender (the client) can communicate with the new receiver (the service). But the response message must support forward compatibility so that the new sender (the service) can communicate with the old receiver (the client). Having one without the other is essentially useless. Supporting both was big part of what lead me to my own versioning model. I'm not saying there are no other approaches to versioning, but if they don't support both backward AND forward compatiblity, then they're not useful in the context of most Web services today.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=24507" width="1" height="1"&gt;</description></item><item><title>Versioning and semantic changes</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2006/05/05/22963.aspx</link><pubDate>Fri, 05 May 2006 18:27:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:22963</guid><dc:creator>tim-ewald</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=22963</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2006/05/05/22963.aspx#comments</comments><description>&lt;P&gt;I got an email a little while ago from someone who read about &lt;A href="http://pluralsight.com/blogs/tewald/archive/2006/04/14/21733.aspx"&gt;my preferred XSD versioning strategy&lt;/A&gt;. They felt I had glossed over the issue of introducing a change that effects semantics and might be ignored by a receiver. Consider this example:&lt;/P&gt;
&lt;P&gt;&amp;lt;element name=&amp;#8221;Deposit&amp;#8221;&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;complexType&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;sequence&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;element name=&amp;#8220;Account&amp;#8220; type=&amp;#8220;tn:AccountIdType&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;element name=&amp;#8220;Amount&amp;#8220;&amp;nbsp;type=&amp;#8220;double&amp;#8220; minOccurs=&amp;#8220;0&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/sequence&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/complexType&amp;gt;&lt;BR&gt;&amp;lt;/element&amp;gt;&lt;/P&gt;
&lt;P&gt;Now suppose I evolved the schema by adding this optional element:&lt;/P&gt;
&lt;P&gt;&amp;lt;element name=&amp;#8221;Deposit&amp;#8221;&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;complexType&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;sequence&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;element name=&amp;#8220;Account&amp;#8220; type=&amp;#8220;tn:AccountId&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;element name=&amp;#8220;Amount&amp;#8220;&amp;nbsp;type=&amp;#8220;double&amp;#8220; minOccurs=&amp;#8220;0&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;element name=&amp;#8220;Currency&amp;#8220; type=&amp;#8220;tn:CurrencyType&amp;#8220; minOccurs=&amp;#8220;0&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/sequence&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/complexType&amp;gt;&lt;BR&gt;&amp;lt;/element&amp;gt;&lt;/P&gt;
&lt;P&gt;The new Currency element is optional so that client who don't send it still work. They use the default currency that was used with the original version of the Deposit message. This works fine as long as you only never have new clients talking to old services. In that case, the client could send a Deposit with a Currency, but the old service would skip that unknown element (as per the rules I described in &lt;A href="http://pluralsight.com/blogs/tewald/archive/2006/04/14/21733.aspx"&gt;my original post&lt;/A&gt;).&lt;/P&gt;
&lt;P&gt;The solution to this problem is to determine whether you will ever have the new client / old service situation (if you're services are deployed as single instance or always updated at the same time before any clients are released, then you never will). If you do, then exercise your judgement about changes. If you are going to change an XSD in a way that alters semantics, make&amp;nbsp;sure you differentiate new instances somehow. For instance, you could add this to your schema:&lt;/P&gt;
&lt;P&gt;&amp;lt;element name=&amp;#8221;DepositWithCurrency&amp;#8221;&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;complexType&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;sequence&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;element name=&amp;#8220;Account&amp;#8220; type=&amp;#8220;tn:AccountId&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;element name=&amp;#8220;Amount&amp;#8220;&amp;nbsp;type=&amp;#8220;double&amp;#8220; minOccurs=&amp;#8220;0&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;element name=&amp;#8220;Currency&amp;#8220; type=&amp;#8220;tn:CurrencyType&amp;#8220; minOccurs=&amp;#8220;0&amp;#8220; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/sequence&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/complexType&amp;gt;&lt;BR&gt;&amp;lt;/element&amp;gt;&lt;/P&gt;
&lt;P&gt;This way you are versioning your schema, but not the Deposit element. This avoids the problem without introducing too much extra complexity.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=22963" width="1" height="1"&gt;</description></item><item><title>Attempting to address Rajesh's concerns about optionality...</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2006/05/05/22961.aspx</link><pubDate>Fri, 05 May 2006 18:16:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:22961</guid><dc:creator>tim-ewald</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=22961</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2006/05/05/22961.aspx#comments</comments><description>My &lt;A href="http://pluralsight.com/blogs/tewald/archive/2006/04/24/22570.aspx"&gt;last post on optional content&lt;/A&gt; triggered a conversation between Rajesh and Jon. Rajesh's main concern&amp;nbsp;is that making almost everything in your schema optional may give you flexibility, but if occurence requirements aren't captured somewhere, then its hard to consume a service (or other XML). That's true - you need to know what's required. The problem is that if you put that info in your schema, and then you need to change it and that requires changing your namespace, then you have&amp;nbsp;a problem. I can see two possible solutions. One is to include occurence info in your schema but make it clear to everyone that you feel free to change it without changing your target namespace. The big issue here is that if you have an XSD used by multiple services that have different occurence constraints, what do you do? You could combine all the requirements and express the weakest, but keeping that up to date over time would be hard. You could have two different copies of the schema, each with different occurence requirements, but then how does the consumer generate code from both in a meaningful way? You could solve this problem by using a common schema with everything optional, and then offering a per-service redefinition of the schema with specific occurence constraints. xsd:redefine would handle that nicely, but you need the tools to know that they're supposed to generate code from the core schema referenced by the redefine. Since none of the mainstream code-gen tools handle redefine, that seems like a dead-end (which is too bad because it *does* capture the semantics nicely). No, I still think you're better off focusing your schema on describing the shape of data, if it is present, and captureing the current rules for what must be present some other way, e.g., documentation. Increasingly, I think of this as a sort of hybrid of static and dynamic typing. At development time, you get enough info to statically compile your code and not be way off base (as you could be with Process(string xml)). But the system is dynamic enough to allow wiggle-room at run-time to compensate for service evolution.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=22961" width="1" height="1"&gt;</description></item><item><title>Initial code for version-aware schema validation</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2006/04/25/22704.aspx</link><pubDate>Tue, 25 Apr 2006 18:22:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:22704</guid><dc:creator>tim-ewald</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=22704</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2006/04/25/22704.aspx#comments</comments><description>&lt;P&gt;When I wrote my &lt;A href="http://pluralsight.com/blogs/tewald/archive/2006/04/14/21733.aspx"&gt;initial post on my new approach to XSD versioning&lt;/A&gt;, I promised that I'd post code. Here's the first cut:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;Program&lt;BR&gt;&lt;/FONT&gt;{&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp; static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; OriginalMain(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt;[] args)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#008080&gt;FileStream&lt;/FONT&gt; xml = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;FileStream&lt;/FONT&gt;(args[0], &lt;FONT color=#008080&gt;FileMode&lt;/FONT&gt;.Open);&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileStream&lt;/FONT&gt; xsd = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;FileStream&lt;/FONT&gt;(args[1], &lt;FONT color=#008080&gt;FileMode&lt;/FONT&gt;.Open);&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; XmlReader&lt;/FONT&gt; reader = &lt;FONT color=#0000ff&gt;null&lt;/FONT&gt;;&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; XmlReaderSettings&lt;/FONT&gt; settings = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;XmlReaderSettings&lt;/FONT&gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; settings.IgnoreWhitespace = &lt;FONT color=#0000ff&gt;true&lt;/FONT&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; settings.ValidationFlags = &lt;FONT color=#008080&gt;XmlSchemaValidationFlags&lt;/FONT&gt;.None; &lt;FONT color=#008000&gt;//ReportValidationWarnings;&lt;BR&gt;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; settings.ValidationType = &lt;FONT color=#008080&gt;ValidationType&lt;/FONT&gt;.Schema;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; settings.Schemas.Add(&lt;FONT color=#008080&gt;XmlSchema&lt;/FONT&gt;.Read(xsd, &lt;FONT color=#0000ff&gt;null&lt;/FONT&gt;));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; settings.Schemas.Compile();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // wire-up anonymous callback delegate&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; badDepth = -1;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;bool&lt;/FONT&gt; nextNodeInvalid = &lt;FONT color=#0000ff&gt;false&lt;/FONT&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; settings.ValidationEventHandler += &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;object&lt;/FONT&gt; sender, &lt;FONT color=#008080&gt;ValidationEventArgs&lt;/FONT&gt; ea)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;.WriteLine(&lt;FONT color=#800000&gt;"Event -- {0}: {1}"&lt;/FONT&gt;, ea.Severity, ea.Message);&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;.WriteLine(&lt;FONT color=#800000&gt;"Event -- {0}\t{1}\t{2}\t{3}\t{4}"&lt;/FONT&gt;, reader.NodeType, reader.Name, reader.Value, reader.SchemaInfo == &lt;FONT color=#0000ff&gt;null&lt;/FONT&gt; ? &lt;FONT color=#800000&gt;"&amp;lt;none&amp;gt;"&lt;/FONT&gt; : reader.SchemaInfo.Validity.ToString(), reader.Depth);&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (reader.NodeType == &lt;FONT color=#008080&gt;XmlNodeType&lt;/FONT&gt;.Element &amp;amp;&amp;amp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader.SchemaInfo.Validity == &lt;FONT color=#008080&gt;XmlSchemaValidity&lt;/FONT&gt;.NotKnown &amp;amp;&amp;amp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nextNodeInvalid == &lt;FONT color=#0000ff&gt;false&lt;/FONT&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;FONT color=#008080&gt;Console&lt;/FONT&gt;.WriteLine(&lt;FONT color=#800000&gt;"Filtering out unexpected stuff now..."&lt;/FONT&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nextNodeInvalid = &lt;FONT color=#0000ff&gt;true&lt;/FONT&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; badDepth = reader.Depth;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;else&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (reader.NodeType == &lt;FONT color=#008080&gt;XmlNodeType&lt;/FONT&gt;.EndElement &amp;amp;&amp;amp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader.SchemaInfo.Validity == &lt;FONT color=#008080&gt;XmlSchemaValidity&lt;/FONT&gt;.Valid)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#008080&gt;Console&lt;/FONT&gt;.WriteLine(&lt;FONT color=#800000&gt;"Other stuff expected, ignoring..."&lt;/FONT&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;};&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;reader = &lt;FONT color=#008080&gt;XmlReader&lt;/FONT&gt;.Create(xml, settings);&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;while&lt;/FONT&gt; (reader.Read())&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (nextNodeInvalid)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; targetDepth = badDepth - 1;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;FONT color=#0000ff&gt;while&lt;/FONT&gt; (reader.Depth &amp;gt; targetDepth)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader.Read();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;FONT color=#008080&gt;Console&lt;/FONT&gt;.WriteLine(&lt;FONT color=#800000&gt;"Filtering -- {0}\t{1}\t{2}\t{3}\t{4}"&lt;/FONT&gt;, reader.NodeType, reader.Name, reader.Value, reader.SchemaInfo == &lt;FONT color=#0000ff&gt;null&lt;/FONT&gt; ? &lt;FONT color=#800000&gt;"&amp;lt;none&amp;gt;"&lt;/FONT&gt; : reader.SchemaInfo.Validity.ToString(), reader.Depth);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nextNodeInvalid = &lt;FONT color=#0000ff&gt;false&lt;/FONT&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;badDepth = -1;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console&lt;/FONT&gt;.WriteLine(&lt;FONT color=#800000&gt;"Main -- {0}\t{1}\t{2}\t{3}\t{4}"&lt;/FONT&gt;, reader.NodeType, reader.Name, reader.Value, reader.SchemaInfo == &lt;FONT color=#0000ff&gt;null&lt;/FONT&gt; ? &lt;FONT color=#800000&gt;"&amp;lt;none&amp;gt;"&lt;/FONT&gt; : reader.SchemaInfo.Validity.ToString(), reader.Depth);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;}&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;What this code does is pretty simple. It catches XSD errors and if they occur at the beginning of an element, which indicates unexpected stuff is present, they ignore that error and any others that occur for that depth in the document. This version also happens to catch XSD errors if they occur on the close tag of an element, which indicates that expected stuff is absent. With optioanl extenstions, this is never a problem, but it was interesting to make it work with extensions that aren't marked minOccurs=&amp;#8221;0&amp;#8221;. Anyway, when it detects extra unexpected stuff, it indicates that that content is &amp;#8220;filtered&amp;#8221; - meaning that it could be removed from the XML stream and the resulting document could be assumed to be valid as per your current schema (you'd really want to do another validation pass to be absolutely sure, but I wouldn't bother in general). My next step is to wrap this in an XmlReader implementation so that it can be piped into a serializer more simply. It needs its own reader because it relies on control of the Read loop to filter stuff out. Anyway, I'll post that when it's working correctly. BTW, one thing to note about this code is that it only works with the sequence compositor. With all compositors, you can't assume that an unknown element is the beginning of content from a later version. I don't have any problem with this limitation, but it has to be mentioned.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=22704" width="1" height="1"&gt;</description></item><item><title>Slogging</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2006/04/25/22648.aspx</link><pubDate>Tue, 25 Apr 2006 12:07:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:22648</guid><dc:creator>tim-ewald</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=22648</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2006/04/25/22648.aspx#comments</comments><description>&lt;P&gt;Now matter which way you tackle contract evolution, you need to have a system in place to notify your service consumers. I envision a system based on &amp;#8220;service blogs&amp;#8221;, or &amp;#8220;slogs&amp;#8221;. A slog conveys information about the state of a service. As a consumer, I want to subscribe to a slog for each service I use. My aggregator becomes a &amp;#8220;dependency dashboard&amp;#8221; that tells me about upcoming service news. One thing I&amp;#8217;d catch this way is upcoming service revisions. Optimally, the revision notification would include a pointer to a test environment and a time frame for testing. I would run my system against the new endpoint in order to test the functionality. If it works, great, I&amp;#8217;m done. If it doesn&amp;#8217;t, I need to figure out what I have to change to make things work again and I need to start a conversation with the service team to coordinate changes on my end and/or their end, as well as plans for when/how I migrate. As long as I&amp;#8217;m on this topic, I should include the need to see basic ops stats bubbling up this way to so that I have a good sense that the services I&amp;#8217;m using are meeting their SLAs. This whole part of the picture, which involves inter-team communication, seems pretty much ignored today. &lt;A href="http://www.mindreef.com"&gt;Mindreef&lt;/A&gt; is the only company I know that&amp;#8217;s addressing it, and they&amp;#8217;re in the early stages.&lt;BR&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=22648" width="1" height="1"&gt;</description></item><item><title>Making everything optional</title><link>http://www.pluralsight.com/community/blogs/tewald/archive/2006/04/20/22187.aspx</link><pubDate>Thu, 20 Apr 2006 18:51:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:22187</guid><dc:creator>tim-ewald</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/tewald/rsscomments.aspx?PostID=22187</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/tewald/archive/2006/04/20/22187.aspx#comments</comments><description>&lt;P&gt;DJ &lt;A href="http://pluralsight.com/blogs/tewald/archive/2006/04/19/22111.aspx#22149"&gt;commented&lt;/A&gt; on &lt;A href="http://pluralsight.com/blogs/tewald/archive/2006/04/19/22111.aspx"&gt;my post addressing the problem&lt;/A&gt; &lt;A href="http://blogs.infosupport.com/raimondb"&gt;Raimond&lt;/A&gt;&amp;nbsp;&lt;A href="http://pluralsight.com/blogs/tewald/archive/2006/04/14/21733.aspx#21764"&gt;raised&lt;/A&gt; with my &lt;A href="http://pluralsight.com/blogs/tewald/archive/2006/04/14/21733.aspx"&gt;versioning strategy&lt;/A&gt;. He wondered if he'd missed an earlier post where I argued that you not use XSD to validate your data because if you make content optional, you can't use it to check what has to be there. Since I haven't written about that yet, I figured I'd start to address it now.&lt;/P&gt;
&lt;P&gt;When people build a schema for a single service, they tend to make it reflect the precise requirements of that system at that moment in time. Then, when those requirements change, they revise the schema. The result is a system that tends to be very brittle. If you take the same approach when you design a schema for use by multiple systems, describing a corporate level model for customer data for instance, things are even worse. Some systems won't have all the required data. They have to decide whether to (a) collect the data, (b) make up bogus data, or (c) not adopt the common model. None of these are good approaches.&lt;/P&gt;
&lt;P&gt;To solve both these problems, I've started thinking about my schema not as the definition of what &lt;EM&gt;this system needs right now&lt;/EM&gt; but as the definition of &lt;EM&gt;what the data should look like if it's present&lt;/EM&gt; instead. I move the actual checking for what has to be present inside the system (either client or service) and implement it using either code or a narrowed schema that is duplicate of the contract schema with more constraints in place.&lt;/P&gt;
&lt;P&gt;The advantage of this model is that I can change the &amp;#8220;has&amp;#8221; requirements without changing the shape of the data. Yes, I'm changing my contract and I need to make sure that clients test against the new version before it all goes live. There's a chance, though, that some or even many clients won't have to change. If I revise the schema itself in a way that forces a namespace change, then I have to support parallel contracts or migrate all clients at the same time. Neither is a good option. In other words, I'm trying to minimize schema changes and use testing to pinpoint required code changes.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=22187" width="1" height="1"&gt;</description></item></channel></rss>