Requirements for an Enterprise Service
An enterprise SOA service is not just any old web service. There are specific requirements that it must meet. These are not optional, yet I have not been able to find many resources on the web describing these requirements. (Reasons = different post).
In general, if you are developing a service that you want other folks to consume, you must follow these high level principles.
- Your service must be simple to call. With a coarse-grained service, there can be a lot of data to pass, and that data may need to be fairly complete. The receiving end may need to perform quite a bit of validation on that data. One tactic that I've seen to 'optimize' this is to write a DLL that creates the data and calls the service. Then you just ship the DLL to your customers. This is nuts.
- You customers still have a call-level interface. Instead of it being the service, it's the DLL. Nothing gained.
- EAI components now need an adapter to call your service. Something lost.
- Your service, if called from an external or cross-platform environment, it is not being called by your DLL. In fact, you cannot really be sure that the service is called by your DLL even inside your environment... so you will have to validate the data anyway. This means that the data, when it is called by your DLL, is validated twice. This is a performance hit. Do it once... in the service.
- Your service must be able to be called directly from EAI components, like Biztalk or your favorite ESB, without engaging an expensive or custom adapter. EAI components have no trouble reading WSDL. Requiring an adapter means that you don't have a truly sharable service.
Implications:- Heavily nested or embedded XML structures are unweildy in most tools. Therefore, the fact that you can do something in XML, doesn't mean that you should. Avoid the creation of the "universal message" that can be extended 1,000 different ways. Go ahead and create messages for specific business purposes. Keep the vocabulary of messages from exploding by using optional attributes and structures... that's fine. But if you create an XSD that refers to 10 other XSD files, you've got a structure that no human can understand, much less code to.
- Requiring some non-standard encryption to take place or some special mechanism to 'encode' the message, to make sure that it is coming from a known source, forces your EAI tool to use an adapter. It also gets in the way of flexibility. To remain flexible, you need the message to come from anyone without changing the code. It is perfectly appropriate to encrypt the message or to sign the message. There are standards for that. Use them.
- If you do want to make a DLL available for folks to call your service, perhaps to reduce the barriers to adoption, do so with open source. If the developers using your code can see the code, and change it, on their side, then you have done them a favor. If you simply substitute your web service call for an API call, you've done nothing positive at all.
- Services running at the Enterprise Level must have methods that can be called to validate (a) that the service is running, and (b) that downstream connections are valid. Therefore, I suggest that every service should have standard methods for "ping" and "check." Note that, for services that have no downstream connections, they both do the same thing. I'd suggest that the return for the call is simple connection information to the service (perhaps the URL of the service itself).
- Services running at the Enterprise Level should provide data about what servers, data centers, and support teams they are associated with, live and in real time. Therefore, I suggest that ever service should have a standard method for "GetSupportData" that returns a structure containing all the info.
- Services running at the Enterprise Level should NORMALLY be asychronous, with a very rapid return of an acknowledgement that indicates that the service itself takes ownership and responsibility for the message.
- The sending side must place a unique id into every call. For async message exchange, the receiving side must send back the caller's unique id, along with any unique id it has created for it's work. This allows message correlation.
- The call-back structure, for calls that require a later return, must be standard, allowing any caller to easily construct the data needed for the receiving system to understand how to call the sender back with the response package.
Of course, putting requirements like this on Enterprise Services means that not every service can partake. On the other hand, it means that every service in the Enterprise catalog can be verified automatically, and basic information can be collected and reported. You can go further, of course, and place a great deal of stuff in a standard interface, but this is the basic set that I would start with.
Comments
Anonymous
December 12, 2006
Very thoughtful post with lots of valid points. Well done.Anonymous
December 20, 2006
Nice take. We have the notion of Channels on our ESB where Services exposed on the Enterprise channel must have many of the characteristics you denoted. What we don't have is the built in Admin/Management operations you describe. I am going to explore that with my team. Other channels on the ESB may be private and provide for less stringent service requirements.Anonymous
January 15, 2007
The comment has been removedAnonymous
January 15, 2007
Hello Benjy, I grant you that the GetSupportData service should only be allowed to be called by users who perform a Support role. Therefore, if a non-support consumer were to make the call, they should get an access violation. That said, I do think that it makes sense that a service should describe where it is installed, even if that adds the effort to change the config file when the service is installed (although a lot of support info, including the name of the server, is available through API calls). If you have a load balanced service running on four servers, and one instance is having trouble, you want to be able to isolate the instance to the specific server. While I agree that an audit trail is necessary, I'm not sure that I would build a GetAuditTrail call into the interface of the service, or if I would have the service call a plug-in to register calls to a common infrastructure. That way, you could pass the name of the service to the audit infrastructure, and it could produce the audit trail. This is not the interesting case, however. A central audit infrastructure can go the extra step of providing end-to-end audit, so that a sequence of calls to a series of composable services orchestrated in a process can be demonstrated in a single audit trail, allowing for not only a reliable audit but excellent information for both root cause analysis and validation of the compensation mechanism.