Technorati Profile Blog Flux Local IT Transformation with SOA
>

Friday, October 9, 2009

The Service Interfaces


Do you want to watch TV? Grab the remote control and press the ON button. To mute the sound, press Mute. Simple. The service interfaces represent a binding contract between the service provider and the client. Ideally, the contract will be as generic as possible so that it can be flexible and you won’t need to change it for trivial reasons.  On the other hand, you have to ensure the interface is complete and sufficiently specific to ensure there are no ambiguities during the request and the response.
The contract should not assume any explicit knowledge between the client and the service provider. In other words, the more abstracted and decoupled the interfaces are between the client and the server, the better.  Imagine if every time you drove to a fast-food window you were expected to order the meal differently depending on who was taking the order.
Web services have gained quick acceptance because they rely on high level interfaces like XML. SOAP (Service Oriented Architecture Protocol) improves the situation even more by enforcing an interface view based upon WSDL (Web Services Description Language) as opposed to a view based upon data structures. Other approaches such as REST (Representational State Transfer) utilize the Web stack to provide suitable abstracted interfaces. However, regardless of the specific interface semantics, the point remains: a good interface should completely decouple the HOW a service provider works from the WHAT the service is offering. In the end, the client of the service doesn’t care whether the TV channel is changed via electronic circuitry or via a little gnome living inside the television (an uncomfortable situation for gnomes these days thanks to the advent of flat screens!).
But returning to our restaurant metaphor. . . You have probably been in one of those fast-food places where you can enter your order via a touch-screen. The result is that instead of having an $8/hour employee take your order, you have an $8/hour employer behind the Kiosk guiding you on how to input the order, and probably making you feel like an ignoramus. Unlike ordering your meal from a human being, using a touch-screen exposes some of the intrinsic processes used by the restaurant, and forces you to follow a specific, usually awkward flow, while ordering. This is one of the reasons touch-screens to order meals have failed to really take hold and, analogously, it’s a reason that an older “SOA Protocol” like CORBA (Common Object Request Broker Architecture) failed to catch-on as well. As with the touch-screen example, CORBA forced the client to match the server interface in a way that was not sufficiently transparent. Similarly, we cannot rightly consider remote object invocation protocols such as RMI (Remote Method Invocation) or the analogous RPC/XML (Remote Procedure Call with XML) to provide true SOA interfaces. These protocols force the client to make assumptions about the object methods and data types, while failing to properly hide the implementation of the service such as the way the called “service” represented by the object is constructed or initiated, and the way various data types are handled.
The difference between a service and a function is subtle, but the way to disambiguate it is clear: If the “function” being called is potentially required to be placed in a separate environment or can be provided by a separate vendor, then it should be defined as a service.  Yes, RMI/Java APIs are okay for “local services”, but beware of this terminology. If you recall the transparency credo, you know that talking about “local” services is a mistake. If you intend to create a true service, then I suggest you expose it properly from its inception. As such, it should always be exposed as a decoupled service with a truly abstracted and portable interface.
Remote Object Invocation and other function-level interfaces fail to meet the implementation transparency credo required by SOA, making the resulting “service-less” SOA system as pointless as decaffeinated coffee or alcohol-free beer.
While some might argue the “merits” in using RMI or RMI-like protocols to improve SOA performance, this performance improvement, if any, comes at the cost of flexibility.  Why? The moment you have to grow the system and try to convert the “local” service into a real service you are bound to face unnecessary decoupling work. This stage of the design process is not where we should be worrying about performance. Creating a function where a service is needed simply to avoid “the overhead” of XML or SOAP is not an appropriate way to design (in any case, said overhead can be minor when using coarse-grained services). Define the services you need first, and then you can focus on streamlining their performance.
Yes, there is a role and a place for RMI and Object Interfaces when you are certain you are creating a function and not a service. Functions are usually fine-grained and can certainly be used for specific intra-system calls to shared common objects. But the bottom-line is this: in case of doubt, use real SOA interfaces.
The beauty of respecting the transparency credo and enforcing the abstraction layer provided by properly laid down service interfaces is that you will then be in a position to leverage the tremendous powers that the underlying service framework provides in rapidly leveraging service ecosystems for the quick delivery of solutions.
More on this next.

Labels: , , , , , , , , ,

Friday, October 2, 2009

On the Granularity of Services


You’re seated in a fancy restaurant ready to enjoy a nice gourmet meal.  The waiter shows up with the menu, but instead of a list of entrees and appetizers, you are confronted with a catalogue of recipes. You order a Tuna Tartare as appetizer. The waiter stares at you with a bewildered expression on his face. “Pardon?” he asks. “I’d like a Tuna Tartare,” you insist. He doesn’t understand and it finally hits you, he’s expecting you to guide him through each step of the recipe. “Heck,” you think, this must be some kind of novelty gimmick, like Kramer’s make-your-own-pizza idea in a classic Seinfeld episode, and so you begin the painstaking process of preparing for the appetizer:
“Please get 3 ¾ pounds of very fresh tuna. Dice the tuna into 1/4-inch cubes and place it in a large bowl.” The waiter scribbles furiously. “Got this part, sir, I’ll be right back!” he says as he dashes to the kitchen to begin preparing your order.
Reading from the menu, you continue when he returns by requesting that he combine1 ¼ cups of olive oil, 5 limes zests grated and 1 cup of freshly squeezed lime juice in a separate bowl. He runs back to the kitchen before you get a chance to tell him to also add wasabi, soy sauce, hot red pepper sauce, salt, and pepper to the bowl. . .
You get the idea.  There are different ways to ask for services. Let’s think of a more realistic computer design choice. Say you need to calculate the day of the week (What day does 10/2/2009 falls on?). If you were to define “Calculate-Day-of-the-Week” as a service, then you would be expected to allow this service to run in any computer, anywhere in the world (remember the transparency credo I covered earlier!), and to be reachable via a decoupled interface call.  If you were to answer, “Okay! No problem”, I would have to then ask you whether this is actually a sensible option. What would be the potential performance impact of having to reach out to a distant computer every time a day of the week calculation is needed?
Remembering the definition of services that I provided earlier, you insist that “Calculate-Day-of-the-Week” is definitely a service that provides a direct business value.
For SOA purposes a service represents a unit of work that a non-technical person can understand as providing a valuable stand-alone capability
You can argue that “Calculate-Day-of-the-Week” is in fact a unit of work that the salesperson, a non-technical person, can understand and that she will need to access with her Blackberry. In that case, I would then yield to the argument because you have shown that the calculation has business logic that is relevant to your company.
If, on the other hand, “Calculate-Day-of-the-Week” is needed only by programmers, and there is no requirement for it to be directly accessed by anyone in the business group, then this is something that should be handled as a programming function and not as a service. 
If the reason “Calculate-Day-of-the-Week” is needed is because the calculation is part of a broader computation, say to find out whether a discount applies to a purchase (“10% off on Wednesdays!”), then the real service ought to be “Determine-Discount” and not a day of week calculation. You see, defining what constitutes a service can be somewhat subjective.
Your team should apply similar reasoning when determining services: Calculating the hash value of a field is a function; not a service.  Obtaining passenger information from an airline reservation system is a service, but appending the prefix “Mr.” or “Ms.” to a name should not be considered a service.
Now, to be fair, there will always be those fuzzy cases that will demand your architecture team to make a call on a case-by-case basis.  If obtaining a customer name is needed for a given business flow, then it can be considered a service. However, if obtaining the customer name is part of a business process that is a part of assembling all customer information (address, phone number, etc.) you should really have a “Get-Customer-Information” service so as not to oblige the client to request each information field separately. 
In general, when it comes to services, it is better to start with fewer, coarser services and then move on to less coarse services on a need by need basis. In other words, it’s better to err on the side of being coarse than to immediately expose services that are too granular. It’s ultimately all about using common sense. Remember the restaurant example. When you order food in a restaurant it’s better to simply look at the menu and order a dish by its name.
Finally, even if a function is determined not to be a service, and therefore does not need to be managed with the more comprehensive life-cycle process used for services, there is no excuse for not following best-practices when implementing it. Just as with services, make certain the function is reusable, that it does not have unnecessary inter-dependencies, and that it is well tested. You never know when you may need to elevate a function to become a service.
But most importantly, the secret sauce in this SOA recipe is the interface: both, services and functions must have well defined interfaces.
More on this next week!

Labels: , , , , , , ,