The problem:
The budget is limited, the back end has huge interfaces and I need only a fraction of that. My sponsor must be convinced that now is the time to expose more.
Case study:
- The desired service is "Change Name&Address Details". This is the actual requirement (I know, not SMART but for this example it will do just fine)
- The back end system exposes a "UpdateCustomerProfile" service which allows changing Name, Address, Privacy settings, Credit Status, Collection Path and collection status and a whole bunch more...
When further designing the services, they find that a whole bunch of services and even more capabilities can be exposed on this back end service UpdateCustomerProfile. When they discuss their findings with the sponsor, he actually dictates that instead of exposing the proposed 10+ granular capabilities, he says I will grant you the luxury of exposing extra functionality as I see the benefit, so you get some extra money however, you must expose it as a single 1:1 service and let the consumer decide which functionality to use. This should also increase the reusability of the service so it's a sure win-win situation and I get more value for money. Let's call this service "ChangeCustomerProfile".
Done deal, right? Why is this a problem? Everyone's happy, everyone gets what they want.
Let's see why this is not the right approach:
- By exposing all the nitty-gritty back end interface details 1:1 they actually kill the decoupled contract pattern used in SOA. The service consumer must now (because of the bottom-up approach) know how the back end system works in order to effectively use the interface on the middleware. Actually, it is as if the middleware did not exist. With or without the middleware, no difference in controlling the back-end. Where the gain?
- As you can see from the new service's name "ChangeCustomerProfile" it was hard to find a name which makes it intuitive for the service consumer to derive from the service name what the service does. The designer of the consumer of this service must now read extensive documentation and carefully decide how to use it in order to avoid invalidating data or breaking data consistency. Hmmm... I always thought that, when it comes to consuming SOA services, the understanding of the system would be better; but nothing changed. One of my next posts will be on service naming. Stay tuned for that one.
- By exposing this extremely large interface to the service consumers (very 'reusable' right? So many consumers), in case something must change the interface, chances are, we have to update many consumers to make sure they all keep working with this service capability. For the people who are now arguing that you don't need to change all the consumers, let's see: you are partially right. But the cost of a system is not just determined by the service delivery effort; there's also something called operation & maintenance. Every operational old version of a service interface, increases your operation and maintenance cost. This is what is referred to as your "IT Burden", which in fact kills part of your SOA strategic goal to reduce the IT burden. So you loose either way: either because next change on your interface triggers many service consumer changes, or because the number of versions of this interface explodes, making operations hard.
- Standardized service contracts: We did not do this at all. Instead of designing interface-first, we created the interface from the back-end exposed interface. This bottom-up approach results in tight coupling between consumer and service provider.
- Service loose coupling: This bottom-up approach, which is also reached when ie. using interface generation tools like java2wsdl, results in tight coupling between consumer and service provider. We may have a decoupled interface from technology and transport point of view, we definitely did not gain loose coupling from exposed back end services.
- Service Abstraction: Instead of exposing capabilities abstracted from the back end, we exposed the back end interface 1:1: no abstraction at all on capability level.
- Service Reusability: This is the one we unintentionally failed despite the sponsors' "efforts". A service is a true candidate for reusability when many of the SOA design principles are applied properly, including #1, #2, #3, #7 (not a guarantee that reuse is reached, but at least the potential for reuse).
- Service Autonomy: because we exposed a too generic interface "can-do-all", we unfortunately disallowed future designers to only use parts of the system which are necessary. Instead, they need to hit that same huge service 'capability' in many situations. By doing this, the autonomy of the service decreases.
- Service Statelessness: Because this service can-do all, chances are there that a lot of state must be passed back and forth. Although the service on itself may be stateless, the knowledge of the back end's data is large on client side. Usually statelessness is a significant driver for the amount of scalability which can be obtained, but so is passing around a lot of data.Worst case, the client must read ALL data the service exposes, to be able to modify and update the back end data.
- Service Composability: Composability is low in this example, in general. The service fails most of the design principles, resulting in low composability.
- Service Discoverability: There is virtually none. The service name nor documentation could give distinguishable content to make it easy to find the appropriate service for the appropriate capability. What can I do with the customer? What is this 'profile'. Is it a form of aggregated data which allows deriving customer value? Is it something related to his visual appearance? What is this thing we're exposing???
- Increased intrinsic interoperability: failed because the technical back end interface was exposed directly to the service consumers. Gone agnostic services. Gone interoperability as composing services can only be done with exhaustive reading and figuring out how this stuff actually works: in fact, instead of making it easy to use this service in other service compositions, you remain on the good ol' integration effort path and will have gained anything in the domain of this goal.
- Increased federation: there is no increased federation. Everything remained as before. Your middleware exposes what your back end provides, no chance of improving federation.
- Increased business and technology alignment: Sort of... on one side, the business is involved during the design process. But next time this service is available and then it remains questionable whether the business is consulted. Benefit of the doubt though I tend to think 'no'.
- Increased vendor diversification options: Actually, no, you are just locked in more to this vendor as now, not just the consumers, but also the middleware is tightly interlocked with the vendor's interfaces.
- Increased Return on Investment: Your initial investment: yes, you get a lot of service (which is not used right away) for your money. But the cost of next changes or the cost of operation will increase and must be included in the ROI calculations as well. So less ROI than expected. The issues typically arise after several years when the environment becomes unmanageable. Since ROI is impacted by the first four strategic goals which we gracefully failed, don't expect anything here.
- Increased organisational agility: We did not help the organisation wrt agility by building this service. In fact, by having yet another IT 'asset' exposing more of the same, in exactly the same way hardly helps improving in this area.
- Reduced IT burden: We failed the first six goals, so what do we get on this one? Right, nothing at all. Probably what we did made managing the solution harder, so your IT burden increases instead of reaching the intended decrease.
No comments:
Post a Comment