A Service is Course, of Course of Course
One of the central tenets espoused by SOA advocates is the concept that information returned by service calls be course grained. At first, this appears to be a foregone conclusion; however, finding the "sweet spot" in your service's returned data and available functionality can be a painstaking process. Your organization's definition of course grained can have a profound impact on the reuse, extensibility and ultimate success of your enterprise SOA implementation.
The definition of what qualifies as a course grained message varies widely. Some treatise advocate a "one size fits all" approach, whereby all information related to a particular subject matter and all operations that can act on that subject matter are bundled into one parametric service. Other recommendations swing toward the opposite extreme, to an extent where service consumers are forced to make seemingly superfluous calls to first gather relevant data and then act on it.
In my experience, a more pragmatic approach enables an environment where SOA's mandate of loosely coupled, reasonably course grained services that are reusable by the most amount of calling applications can be realized, without sacrificing performance, scalability, or security. Here are a few simple rules to guide you through the process of defining the granularity of your service processes:
- Identify topical areas - services should be defined around these topics, or "data silos".
Take the example of an application which contains customer information for an e-commerce company. Each customer will have address (mailing, billing), contact info (name, email, phone), billing info (credit card number, bank account), products purchased, items clicked on, wish lists. Possible internal consummers for a Customer web service would be a Billing application, a Shipping app, Marketing Trends Analysis app, etc. The Billing application only needs information regarding the customer's contact info, credit card and bank account info, and billing address - it doesn't need a customer's shipping address or the products that customer has purchased (though, the Shipping app would probably need that information). The Shipping and Marketing Trends apps will need the customer's contact info, address(es) and products purchased, but their needs diverge beyond these similarities. The topical areas surrounding the customer in this example can be extrapolated by reviewing not only what a single application requires, but by identifying convergence points between consumming apps.
- Identify functional areas - separate data from logic as much as possible.
A tendency in service architecture is to create services which permit the range of CRUD (Create/Read/Update/Delete... can someone please create a better acronym for this?) operations, which can be executed parametrically via a single service request model. I strongly advise against doing this. Separating logic from data - a core concept of run-of-the-mill object oriented analysis and design - should be carried over naturally into SOA. This applies to WREK (Write/Read/Edit/Kill... hey, it's better than CRUD) operations and especially to more complex business logic which may be applied to info returned by your service.
This is not to say, however, that business logic should not be available parametrically within the initial service call. Returning to the Customer app from the previous example, say that I wanted to allow calling apps to request only those customers which made purchases on a specific date, or only those customers who had made visits to the site within a specific time frame. The initial service request should allow consumming apps to specify these parameters as part of the request, rather than having to filter the entire set of records returned by the service.
- Build services atomically - aggregation should be handled via orchestration.
There will always be applications which need access to info or business logic provided by your services which fall somewhat outside of the lines you've drawn to define your service functionality. In these cases, rather than building one-off services to accommodate these consummers, it is better to use service orchestration techniques - where a facade is built to marshall multiple services and aggregate their collective responses for calling applications - to satisfy their requests. Orchestraton is a deep topic, which I will approach in another blog post, though I thoroughly encourage research into this area if believe you've reached a situation that calls for orchestration.
- Identify generic and utility needs - decide if it adds value to build services for these activities.
All services require security considerations, logging, message validation; some will require orchestration, message transformation, etc. Depending on the extent of SOA within your enterprise, it may make sense to create centralized utility services which can in turn be called by other services. Generally, use of SOA should either be extensive or projected to become extensive to justify the creation of these kinds of services.