Interface-based programming and Web services: Part 1

This post made it out into the wild before its time. If you were unfortunate enough to have your aggregator pick up my half-baked post, I apologize. Note to self: Save is the same as Post for new items in NewsGator. This is one of those blog entries that started as one thing, morphed into another and grew in size as it was written, resulting in the need to break this into a couple of different parts to maintain coherent thoughts and guide you, the reader, through the clutter of my mind. Hopefully it’ll be worth the read.

I need to give some credit to WebSphere Studio Application Developer (WSAD) here. WSAD has a feature that allows you to select a Java class and deploy it as a Web service. WSAD then creates the Web services wrapper and delegates the Web service calls to the object. Don’t mistake this moment of praise as me being all gushy for WebSphere … this model for Web services only earns IBM checkmark bragging rights for, “You don’t have to write a line of code to deploy existing code as Web services.”  

 

The problem created by the above is that deploying an existing object as a Web service does not always lend itself to a good Web service (and experience shows that deploying objects as Web services in this manner from within WebSphere is fragile at best, and definitely not very interoperable. Note, this is based upon my experience with WebSphere Studio Application Developer 4. I hear it gets better with 5, but I’ve not had the chance to play around with it … yet. ) The object may return a type that is not represented well as XML Schema, such as a .NET DataSet or a Java vector, or the object may have fine-grained method signatures that tend to perform poorly in distributed systems.

 

So then, what’s the “right” way to expose pre-existing objects with tested, debugged and proven code as a Web service? I offer up that Web services should implement a well-defined interface, and invoke business objects through a façade. The result of this pattern is:

 

  1. Thinking about the interface means thinking about the WSDL
  2. Thinking about the WSDL means thinking about the messages
  3. Thinking about the messages means thinking about the XML Schema
  4. Thinking about XML Schema means thinking about interoperability
  5. Thinking about interoperability is goodness and wholesome

 

This is not to say that I’m a message-first or even a WSDL-first developer. Nothing could be further from the truth. Personally, I do not believe that hacking out XML to craft my messages and my WSDL is an efficient use of my time. However, the way I think about the implementation when writing my C# code is in terms of the XML Schema of the messages and the resulting WSDL. I would be willing to change this behavior if the tooling of Visual Studio .NET lent itself to a WSDL-first model, but it does not.

 

Therefore, instead of falling prey to the myriad of .NET Framework samples that do this:

 

[WebService(Namespace="https://weblogs.asp.net/kevinha")]

publicclass Service1 : System.Web.Services.WebService

{

      [WebMethod]

      public string HelloWorld()

      {

            return "Hello World";

      }

}

 

I suggest you declare an interface that serves as your public declaration to the world of what this Web service can do. In the Web service implementation of the interface, you do little more than invoke a façade from within the actual WebMethod. The façade, in turn, invokes the actual business object and performs any necessary transformation from the business object’s native formats to that required by the interoperable interface. The resulting implementation of this pattern looks something like this:

 

publicinterface IHelloWorld

{

      string HelloWorld();

}

 

[WebService(Namespace="https://weblogs.asp.net/kevinha")]

publicclass Service1 : System.Web.Services.WebService, IHelloWorld

{

      [WebMethod]

      public string HelloWorld()

      {

            IHelloWorld h = new HelloWorldFacade();

            return h.HelloWorld();

      }

}

 

publicclass HelloWorldFacade : IHelloWorld

{

      public string HelloWorld()

      {

            Messenger m = new Messenger();

            return m.Message();

      }

}

 

publicclass Messenger

{

      public string Message()

      {

            return "Hello World";

      }

}

 

You’d be correct to state that the above, which I’m advocating as a “proper design pattern” has far more code that the “improper design pattern.” In Part 2, I’ll extend upon this simple “Hello World” sample and you should begin to see the value this pattern brings.