The term Service Oriented Architecture (e.g. SOA) is thrown around quite a bit these days and it always amazes me the speed in which people jump into them and the assumptions they make. There is no doubt that SOA adds a positive dimension to any application architecture. I have been building and deploying webservices for close to 2 years now. Before that I worked on a number of other service based architectures and there are things to consider before jumping into them.
- SOA is just one dimension of a good architectural scheme. It is not THE architecture.
- In some respects (but not all) SOA and OO are orthoganal. OO is about keeping data and the methods and properties that act on the data in the same class. With an SOA architecture, client proxies are generated by the WSDL. Only public properties with getters and setters are created in the proxy. All methods and any business logic is NOT generated on the client nor included in the client proxy. This leads some to actually put the class that is being serialized onto the client as well (yes I have seen people do this/try to do this on a # of occassions) which can cause name collisions and really negates the positive aspects of SOA. If you want to put the class being serialized on the client, then you should take a serious look at Remoting.
The fact that the client proxy only contains the class's getters/setters, leads many developing SOA architectures to seperate business logic classes from their business entity classes. The benefit of this seperation is a positive one but clashes with some OO principles because you are seperating data from the methods and Business Logic (BL) that act on the data. The BL that supports acting on the data is on the WebService machine and the class that gets serialized from the webservice is a seperate Business Entity object and the basis for the Client Proxy (via WSDL).
This is not to say that you cannot follow a stricter OO model by keeping the two together but often times it causes confusion by users of your libraries who are unfamiliar with the way client proxies are generated on the client and expect the methods and business logic to show up on the client in the same proxy ...which does NOT occur. Personally, I recommend the seperation by keeping business entity classes and business logic classes seperate and knowing full well that I have broken the OO model to some degree...the benefit (IMHO) outweighs the costs.
- Remoting and SOA are not the same. Remoting follows the OO paradigm much more closely by providing a Marshal-By-Ref (or a MBV if you know what you are doing) proxy to the actual objects and its methods and properties. This means you can actually call the methods on the object itself via a client proxy and the business logic remains in tact. This follows the OO paradigm much more closely then a WebMethod because the client proxy is aware of the business methods and the business logic encapsulated in the object itself which isn't available with a WebMethod implementation. Furthermore, remoting assumes a .Net implementation which enables you to keep (and often requires) the class being proxied to exist on the client.
- Exception handling with an SOA architecture is different. You can still use the try/catch metaphor but all exceptions are of type SoapException (there is also SoapHeaderException but this means no detail block). This means that their is no differentiation in error typing. In other words, all exceptions emanating from a web service are of type SoapException. There is no way to distinguish between exception types without looking at the DetailBlock in the SoapException and developing your own "contract" between server and clients. I wrote a blog that provides some insight into how to use this detail block to your advantage http://weblogs.asp.net/mnolton/archive/2003/09/17/28015.aspx; however, there are some shortcomings of this approach. The client must know to look at the detail block correctly in order to act on the information it contains. The only alternative is to just show your client whatever error information comes back from the service...but this prevents your client application from acting on the exception in a meaningful manner (which I personally think is a bit of a hack because you cannot really control what a server is going to tell you).
It would be nice feature to provide a "Throws" construct similar to what Java does that would enable someone to decorate a method with a custom attribute(s) that details the exceptions that can emanate from the client. Then in the client proxy, generate an exception proxy (I think this is already supported) but then also generate proxy code that evaluates error conditions and throws the correct exception from within the client (not supported with WSDL.exe). Hmmm, it would be a nice feature for Christian Weyer's WsContractFirst tool :)
- Just because you can create a WebService doesn't mean you should. The cost of traversing the SOA boundary is high. For example, I have seen a number of people try to put a WebService interface over their database. What's the point? If you want to talk to a database, use native libraries in your language of choice. It is much more efficient. Also, a WebMethod should expose a business contract...not a data contract. If you provide just data to your client then you are now tying your client to your data implementation. If that should change then your client is screwed. Instead, create a business contract and make data access a concern of your BL that is called by your WebService. Don't tie your client to it. Often times when I see this it is by a developer who just want to create a WebService.
As always comments and feedback are encouraged.
-Mathew C. Nolton