We are striving towards an SOA enterprise...
Given three options for say updating member details how do we design the contract?
The business process is quite simple. The customer calls (or logs in themselves), and updates their personal details so that we have the latest details available. The customers employer can also supply members details (this will be in bulk - potentially 10s of 1000s at a time). This is so we can communicate with them correctly in the future. We have multiple back end systems.
The details are:
- Phone numbers,
- Addresses,
- Email,
- Name or company name,
- Contact person,
- Tax File Number,
- Marital Status
- Smoker status
As it stands now the business rules are: If a valid tax file number has already been supplied, you cannot supply it again. (can be overridden) If valid address details are present, the employer cannot update them, only supply them the first time.
Option 1: One operation, Member.UpdateDetails
- Only one service to create and manage.
- If business rules grow, this service could become less cohesive.
- Has the problem of having to differentiate between specifying that something should be removed versus leaving it as is.
- Single unit of work, single transaction.
Option 2: Break down into four operations: Member.UpdateContactDetails; Member.ProvideTaxFileNumber; Member.UpdateName; Member.UpdateDemographics
- Potentially simplifies the single operation - spreads the complexity over the four operations.
- Still has the problem of having to differentiate between specifying that something should be removed versus leaving it as is. For example what if I only wanted to specify smoker status without marital status.
- Requires some deep analysis to figure out how to group these correctly - The cohesiveness depends on the business process.
- More services to write and maintain.
- Transactions become a concern - multiple transactions handled by the caller?
Option 3: Break down into smaller still: Member.UpdateAddress; Member.UpdateBusinessDetails; Member.UpdateContactNumbers; Member.UpdateContactPerson; Member.UpdateEmailAddress; Member.UpdateMailingAddress; Member.UpdatePhysicalAddress; etc.
- Removes the issue of having to differentiate between specifying that something should be removed versus leaving it as is.
- Business rules can evolve easily in whatever operation.
- Loads of services to write and maintain.
- Transactions become a concern - many transactions handled by the caller?
- Start to look like property setters / CRUD - apparently a no go.
In option one or two, say the caller only wants to update the home email address - I cannot expect that the client complete the entire message - does the client leave all of the other tags out? What is the accepted, obvious, intuitive pattern to dealing with this problem?
If this IS indeed the pattern, then how does the client clear the field, or set it to null? In .NET, in the server code I cannot see an obvious way to distinguish between not supplied and null. Since it is not obvious, I expect that this is not an accepted pattern.
Use a coarse grained api with fine grained arguments. If you don't want a field to be updated, pass along a descriptor saying that along with the data. Something like:
Having a fine grained API is basically death, because transport is often obscured.
If someone writes:
They have very likely just made a) 3 trips over the network along with b) 3 trips to the DB, concluding with c) 3 transactions on the DB. This doesn't count all of the marshalling and unmarshalling fun involved.
Which, of course, is insane.
Is a service API required to be remote? No, of course not, but many are, and minimally, many are transparent of transport (could be local or remote, you don't know).
So. Coarse API, fine grained arguments. Figure out what you want to do, in detail, and do it all in one go.