Two Web Service "Don'ts"

There are at least 2 things I'm still seeing in some web service implementations we should not be seeing. In my first post, Refactoring XSLT , I was shooting for original ... interesting ... maybe even useful ... but not a best practice (at least not until more testing is done). In this post I'm writing about 2 best practices - independent of the platform (.NET, J2EE, etc) being used. One of them you've [hopefully] heard 1000 times and this will be your 1001st. You might not have heard the other one before ... or at least heard the rationale behind it.

Don't code on the edge

Web Services are essentially the buttons and textboxes other applications use to access some functionality. The endpoint (an ASMX file in the case of .NET) is just that ... an endpoint ... and that's all it should be. You have no business putting application logic in an ASMX page (or its codebehind) than you do in a windows form. I would even go as far as to say there should only be one line of code (2 at the max) in each of your exposed operations. How 'bout an example?

public TempResponse GetTemp( TempRequest tempreq )
    return TempCalculator.GetTemp( tempreq );

As you can see, I'm calling a static GetTemp() method on a different class and returning its result. There might be another line if you have to call an instance method or maybe even another one if TempCalculator is on a different physical tier like Michele illustrates here, but the important thing to notice is the lack of any "temperature" code in the method's body. Let your business logic do that and put it in a different library assembly. "What's the big deal Don? Why not just put it in the codebehind?" If proper analysis and design have been accomplished on the business logic, it actually won't fit on the edge very easily. So, if you have business logic on the edge (in the endpoint operations or in the user interface) there's a very good chance the business logic has a poor design. Forcing the business logic in a separate library encourages solid software design.

One parameter and one return to rule them all

I'm actually illustrating this in my little WebMethod above. I'll admit my tent is pitched in the very middle of the messaging camp (opposed to the RPC camp), but that's not why I recommend only one input parameter and a single return type on all Web Service operations. The reasons really revolve around versioning and interoperability. I've been writing an article on versioning Web Service for months now to eventually be published on MSDN. I thought I lost it on a bad hard drive, but thanks to my close friend Yex, who still had a draft I sent him, I didn't have to start over from scratch. You'll have to take my word for it for now, but in the article I show how it is much easier to version datatypes (parameters and return types) than it is the interface of the operation. In other words, it's much easier to add a ZipCode member to our TempRequest type than it is to add a ZipCode parameter to our GetTemp() method while retaining compatibility with older and newer versions. We've also found the serialization behaviors between .NET and other platforms is very comparable with regard to custom types (opposed to primitive types). Lastly, it's a nice consistent pattern ... no surprises.

I think one of the reasons we're still seeing these bad practices is because developers aren't hearing and seeing them put in place often enough. DonXML talks about this problem in more detail here. I too have been guilty of using bad coding practices in demonstrations and sample code. Of course the main reason we do it is because we're trying to illustrate a certain concept and don't want to spend the time to work up a solid design. We also don't want to confuse the recipient with details outside of the thing we're trying to illustrate. So what's the answer? I think if we just point out the bad practices to the recipient - either using code comments or verbally - it would go a long way to curb this problem. You also know as well as I do that many real-world applications are just demos and sample code that has evolved. Let us all keep reminding everyone about the dangers of ignoring a solid design over productivity - becuase doing so will cause productivity to suffer eventually. Happy coding!