On the project I am currently working on we have several layers of processing going on:
- External Systems (silos)
These are the legacy systems that contain all the information.
- A service layer (WCF)
These Domain Services expose the legacy systems transparently. Talking to these services gives you no clue which legacy system is used. Sometimes its more than one.
- An Enterprise Service Bus (BTS2006R2/ESB)
Positioned as messaging middle ware. For the most part completely transparent to the clients.
- Client / Front end applications (SL3)
User applications that consume domain services through the ESB.
In order to let our domain services perform optimal with the many calls that they’ll receive and to make them as versatile as possible, we’ve decided to do two additional things:
- Support Batching
Most service methods can handle multiple requests at a time. Its like taking your normal service operation contract and putting a collection around it. This enables the client to (for instance) resolve multiple IDs in one single call / round trip. It is the classical choice between multiple calls with small messages or less calls with larger messages. The client can now choose how it wants to interact with the service.
- Support Prefetching
We define a rich data model that each of these domain services work with. These services go beyond just ‘Customers’ or just ‘Orders’. Because all data within a domain service is so related / connected we felt that it would be best to keep it all in one service. But you do not always want all ‘Orders’ and all ‘OrderItems’ and all ‘Product’ for a ‘Customer’. So we allow most service operations to specify what we have called ‘Prefetch paths’. Basically you call the service operation and you specify what relations of the root entity that operations serves up you want also to be included in the response. So you could call GetOrders with only the ‘OrderItems’ prefetch key. That would result in all Orders and OrderItems for a Customer. The client once again is in control of what data is retrieved to suit its needs.
We understand that implementing services this way is somewhat non-standard (I have never seen it done before), but we feel that it provides a lot of flexibility to its clients. For a service to be reusable in a number of different contexts, we believe it should be more flexible that your normal, plain vanilla service. Nontheless, we really like some community feedback on this design and would appreciate any suggestions you might have.