Wednesday, April 27, 2005

Contract First? Code First? Both First.

The recent debate (here, here, and here, amongst others) might lead you to believe there are two ways to design a web service: code-first and contract-first. A surface reading of the debate seems to indicate that you either write a bunch of classes and rely on the vendor to generate the XML (code-first) or write all your WSDL/XSD by hand (contract-first). This is utter crap.

Just like anything else, it all comes down to Splosky's Law. Roughly paraphrased, it reads, “There is no free lunch.“ You don't get to ignore the wire format, and you don't get to ignore the tools. Instead, you have to remember things like, “CLR value types don't work very well in the face of missing elements, but Java works differently.“ You, lucky coder, have to remember that you're writing a system in which the parts might look something like this:

Java <-> Axis <-> XML <-> HTTP <-> XML <-> System.Xml.Serialization <-> ASP.NET <-> C#

And that every layer has its own oddities and idiosyncrasies. If you can do that by writing a pile of classes, great. But you simply won't be able to guarantee success unless you know how those classes turn into XML. You might get lucky, but that's pretty much the same thing as saying, “Well, there was a threading bug, but I ran it again and it didn't happen, so it must not be a problem.“ Similarly, you can't just hurl an XSD at the world and expect that everyone will write code to consume the corresponding XML directly off the wire - they're going to use vendor toolkits for the simple economic reason that it's too expensive not to.

Note that I'm not putting words into the mouths of any of the participants in this debate. Many of them make the same points, although not, I think, in the same “camp neutral“ vein. My point is that you can claim to be either a “contract-first” or “code-first” person and still succeed. Which pretty much makes the distinction (and therefore that aspect of the debate) pointless.

No, call yourself whatever you want, but you still get to learn the stack from end-to-end. Programmers hate this because they spend their life building abstractions, and this flies right in the face of that. Vendors hate it to admit it because it means they can't sell toolkits that “take care of everything for you.” (Not that they don't try.) But at the end of the day, the universe doesn't care that we don't like it - it's still the case that abstractions leak, and knowledge is the only insurance.


  1. It must be that Minnesota upbringing that makes both us have the same viewpoint Craig. I really couldn't agree more that the contract-first/code-first debate is totally pointless. What is true is exactly what you said - if I choose code-first I have to know *exactly* how my code translates to XML. If I do contract-first - I have to know *exactly* how my XML translates into code. See BizTalk for an example where you can do total contract first and not have to worry about any translation to code - assuming you don't want to turn XML instances into .NET objects - but you do have to know that translation in the case where you *do* want to create .NET objects from your XML (or where you end up using straight asmx for example).

  2. I am glad that someone has finally stated publicly what has been nagging at me privately as I follow this debate. The real answer it that "It just has to work end-to-end", no matter where you start. It is impossible to code first at one end without knowing how one tool converts to WSDL and other tools covert back to code. While it would appear to be better to start in the middle with the WSDL, but that will likely end in failure without understanding how the WSDL translates back to code on either end. The approach that I have been generally successful with is to write/modify code on either end until each end generates equivalent WSDL. What can that possibly be called?

  3. Yes! Yes! Yes!

    Good comments, too.

    There is a methodology I love that expresses these types of end-to-end "adaptation patterns" (for lack of a better word) extremely well.

    Just spend about 40 hours reading (at least to chapter 10) to see if you agree with me. I wish Desmond's work had taken off more - I think it was too far ahead of its time.

  4. Jim: what can it be called? How about "practical". :)

  5. How about "Sanity First" development. ;)

    I totally agree with your point. Personally, I'm in the "know your XML, but let the framework do grungy string generation" camp.

    XML to object serialization is the mother of all leaky abstractions - you simply have to know what's going on in there. But if you do, it's a great time saver.

  6. I have been part of both: there were times when I had the classes without the need for web services but at a later date needed to expose them as web services (which caused trouble sometimes) and there were times when I was dictated to start from a XSD/WSDL. As Craig points out there is just no right way and a wrong way. It all depends on the different parts involved in the solution.

    I have been working on few BizTalk projects recently in which it is always Contract-First because you always st

  7. (warning:&nbsp; long, essay post)

    Today I feel centered.&nbsp; Not balanced, not inverted, but centered.&nbsp;...

  8. Generally 'code first' vs 'contract first' is probably best looked as a philosophical, or as you say 'religious' debate. However, this debate does have real world implications. In the 'contract first' situation you define the on the wire format and are forced to write code on both sides, *regardless of your choice of tools*, that handle it. This is harder but you know that if it doesn't work you implemented the contract wrong. In the 'code first' approach the contract is a reflection of your implementation (and quite possibly what patches you've applied.. what version of ASP.NET you're running etc.) and you have little control going from ASP.NET 1 to ASP.NET 2 what happens to your WSDL automatically (ie changes to make ASP.NET 2.0 generated WSDL ws-i BP 1.1 compliant). Further, your auto-generated 'contract' doesn't tell you what's required to implement an interface.. rather just what the tool can swallow...

    This might be fine for small numbers of very flexible clients but for providing a stable endpoint that specifies what is needed you need contract first.

  9. And in practice what happens is you have to be aware of the differences between ASP.NET 1 vs 2, Java clients vs. .NET clients, etc. etc. because your clients don't care about your philosophy. Most of them just want you to give them something that works with their toolkit.

    I wouldn't call this "contract first" because the way that term has been used implies that the wire format is paramount, and toolsets don't matter. This is not in fact true. They matter a lot, because without them most of your clients don't have access to your service.

    Or, as my friend Tim likes to say, "Make it easy for your clients to pay you."

  10. If you really are doing 'contract first' your tools can certainly make things more frustrating for you. However, if you are actually implementing the contract correctly, your frustration will not matter to your client. The contract itself must, of course, be written in a way that will be useable by your clients... but that illustrates the point that the contract should be the focus, rather than letting it be simply a reflection of your tools.

  11. The point the post was trying to make was that in order to write "correct" contracts, you must understand the tools your clients will be using. If you don't, then it's currently easy to write contracts they can't consume. So, yes, you have to put the contract first...but the contract must be constrained by the tools your client will use. This is true whether you author the WSDL in notepad or generate it out of a bunch of Java classes automatically.

    Which is why I say, "Both first". At no point did I claim or intend to imply one should "[let] it be simply a reflection of your tools". In fact, the last sentence of the original post points out that vendor claims of abstraction by tool are so much BS.

    If you want to call this focusing on the contract, that's fine by me. My only point is that to be successful, you must understand the limitations of the tools, and you must understand the details of the contract. Both are equally important if you want to interoperate in the real world.