Are Services Nouns or Verbs?                             Document ID:
ZAPFLASH-20091014 | Document Type: ZapFlash
By: Jason Bloomberg | Posted: Oct. 14, 2009

ZapThink revels in stirring up controversy almost as much as we enjoy
clarifying subtle concepts that give architects that rare "aha!" moment
as they finally discern the solution to a particularly knotty design
problem. Last month's Process Isomorphism
<http://www.zapthink.com/report.html?id=ZAPFLASH-2009915>  ZapFlash,
therefore, gave us a particular thrill, because we received kudos from
enterprise architects for streamlining the connections between Business
Process Management (BPM) and Service-Oriented Architecture (SOA), while
at the same time, several industry pundits demurred, disagreeing with
our premise that Services should correspond one-to-one with tasks or
subtasks in a process. Maybe we got it wrong, and inadvertently mislead
our following of architects? Or perhaps the pundits were off base, and
somehow ZapThink saw clearly a best practice that remained obscure to
other experts in the field?

Upon further consideration, the true answer lies somewhere in between
these extremes. Now, we're not reconsidering the conclusions of the
Process Isomorphism ZapFlash. Rather, further explanation and
clarification is warranted. As with any best practice, Process
Isomorphism doesn't apply in every situation, and not every Service
should correspond to a process task or subtask. That being said, there
is also a good chance that some of our esteemed fellow pundits might not
be opining from a truly Service-oriented perspective, as many of their
comments hint at an object-oriented (OO) bias that may be too limiting
in the SOA context. In fact, understanding which Services the Process
Isomorphism pattern applies to, and how other Services support such
Services goes to the heart of how to think about Services from a SOA
perspective.

The Object-Oriented Context for Services
In the early days of Web Services, as various standards committee
members tried to hash out how core standards should support the vision
of SOA, the SOAP standard for message transport was an acronym for the
"Simple Object Access Protocol." The reasoning at the time was that
Services were interfaces to objects, and hence Service operations should
correspond to object methods, also known as remote procedures. SOAP was
nothing more than a simple, XML-based way of access those methods. Over
time, however, people realized that taking this Remote Procedure Call
(RPC) approach to Service interfaces is too limiting: it leads to
tightly coupled, synchronous interactions that constrain the benefits
such Services could offer. Instead, the industry settled on document
style <http://www.zapthink.com/report.html?id=ZAPFLASH-2006712>  as
being the preferred interface style, which expects requests and
responses to conform to schemas that are included in the Service
contracts by reference, where the underlying Service logic is
responsible for validating interactions against the relevant schemas.

Document style interfaces provide greater loose coupling than their
RPC-style cousins because many changes to a Service need not adversely
impact existing Service consumers, and furthermore, document style
interfaces facilitate asynchronous interactions where a request need not
correlate immediately with a response. In fact, the W3C eventually
dropped the "Simple Object Access Protocol" definition of SOAP
altogether, and now SOAP is just SOAP, instead of being an abbreviation
of anything.

However, document style interfaces still allow for operations, only now
they're optional rather than mandatory as is the case with RPC-style
interfaces. The fact that operations are optional is a never-ending
sense of confusion for students in our Licensed ZapThink Architect
<http://www.zapthink.com/eventreg.html>  course, perhaps because of the
object-oriented pattern of thinking many of today's techies follow,
often without realizing it. How would you ever know what a Service is
supposed to do, the reasoning goes, if you don't call an operation on
that Service? The answer is straightforward: if a Service has no
operations, then what it's supposed to do is understood from the context
of the Service itself. For example, an insurance company may want a
Service that simply approves a pending insurance policy. If we have an
approvePolicy Service, the consumer can simply request that Service with
the policy number of the policy it wants to approve.

Nouns vs. Verbs
The insurance policy example brings up a fundamental question. Which is
the Service, the insurance policy entity or the approve policy task? In
other words, should Services be nouns or verbs? It's possible to design
Services either way, as Entity Services, which predictably represent
business entities, or as Task Services, that represent specific actions
that implement some step in a process, in other words, verbs. Which
approach is better?

If you look at the question of whether Services should be nouns or verbs
from the OO perspective, then Services are little more than interfaces
to objects, and hence it's best to think of Services as nouns and their
operations as the verbs. For example, following the OO approach, we
might have an insurance policy object with several operations, including
one that approves the policy, as the following pseudocode illustrates:

myPolicy = new Policy ();
...
successOrFailure = myPolicy.approve ();

The first statement above instantiates a particular policy, while the
second one approves it, and returns either success or failure.

Now, it is certainly possible to create a Policy Service as an Entity
Service that has an approve operation that works more or less like the
example above, with one fundamental difference: because Services are
fundamentally stateless, you don't instantiate them. Here, then, is
pseudocode that represents how an Entity Service would tackle the same
functionality:

request to create new policy, specifying create policy operation -->
Policy Service --> response with policy number 12345
...
request to approve policy 12345, specifying approve policy operation -->
Policy Service --> response with success or failure

Note that we're representing Service interactions as input and output
messages that contain documents, where in this case, the input documents
specify operations. In this example, there is no object in the OO sense
representing policy 12345 and maintaining the state information that
indicates whether or not that particular policy is approved or not.
Instead, the underlying Service implementation maintains the state
information. There is only the one Policy Service, and it accepts
requests in the form of XML documents and returns responses, also in the
form of XML documents. If a request calls the create policy operation,
then the Policy Service knows to create the policy, while a request that
specifies the approve policy operation follows the same pattern.

Note that the fact that the Policy Service has a document style
interface gives us two advantages: first, we can make certain changes to
the Service like adding new operations without adversely impacting
existing consumers, and second, its stateless nature enables
asynchronous interactions, where instead of returning success or failure
of the approve request, perhaps, the Service returns a simple
acknowledgement of the request (or perhaps no response at all), and then
notifies the consumer at some point in the future that the policy has
been approved, either through a one-way notification event or possibly
as a response to a further query.

Task Services as Verbs
While there is a significant role for Entity Services in SOA, it is
important to break free from OO-centric thinking and consider other
types of Services as well that serve other purposes. In fact, there is
another way of offering the same functionality as the Entity Service
above where the Services represent verbs rather than nouns, what we call
Task Services. Here is the pseudocode for this situation:

request to create new policy --> createNewPolicy Service --> response
with policy number 12345
...
request to approve policy 12345 -- > approvePolicy Service --> response
with success or failure

In this example, neither Task Service has any operations, but rather the
functionality of each Service is understood from the context of the
Service. After all, what would an approvePolicy Service do but approve
policies? If you read the Process Isomorphism ZapFlash, the benefits of
delivering capabilities as Task Services is clear. If you design each
Task Service to represent tasks or subtasks in business processes, then
it's possible to build a Service-Oriented Business Application (SOBA)
that is isomorphic to the process it implements.

Combining Entity and Task Services
A casual reading of the Process Isomorphism ZapFlash might lead you to
think we were suggesting that all Services should be Task Services.
However, in spite of the fact that architects with OO backgrounds often
rely too heavily on Entity Services, such Services do play a critical
role in most SOA implementations. Remember that in the enterprise
context, Services expose existing, legacy capabilities and data that are
typically scattered across different applications and data stores,
limiting the enterprise's agility and leading to high integration
maintenance costs, poor data quality, reduced customer value, and other
ills all too familiar to anybody working within a large organization's
IT department. SOA provides best practices for addressing such issues by
abstracting such legacy capabilities in order to support flexible
business processes.

Both Entity and Task Services help architects connect the dots between
legacy capabilities on the one hand, and flexible process requirements
on the other, as the figure below illustrates:



Process, Task, and Entity Service Layers

In the figure above, the bottom row contains Entity Services, which
directly abstract underlying legacy capabilities. Above the Entity
Services lie the Task Services, which may actually be abstractions of
individual operations belonging to underlying Entity Services. The top
layer contains Process Services, which are typically compositions of
Task Services. In other words, Process Services are interfaces to SOBAs,
and when those SOBAs are compositions of properly designed Task
Services, they will exhibit process isomorphism.

The essential question for the architect is which capabilities to
abstract in which Service layer. Take for example the Address Change
Task Service. Changing addresses is a common example of a particularly
challenging task in many large organizations, because address
information is typically maintained by different applications and data
stores in a haphazard, inconsistent manner. To make matters worse, there
may be addresses associated with customers, policies, or other business
entities.

When architecting the Customer Entity Service, the core design principle
is to pull together the various instances of customer-related
information and functionality across the as-is legacy environment into a
single, consolidated representation. Such a Service will likely have an
update address operation, and the Customer Entity Service's logic will
encapsulate whatever individual queries and API calls are necessary to
properly update customers' addresses across all relevant systems.

The Address Change Task Service, then, abstracts the Customer Entity
Service's update address operation, as well as whatever other address
change operations other Entity Services might have. The Service logic
behind this Task Service understands, for example, that insured
properties in polices have addresses and customers have addresses, and
these addresses are related in a particular way, but are by no means
equivalent.

The ZapThink Take
As is usually the case, architects have several options at their
disposal, and knowing which option is appropriate often depends on the
business problem, an example of the "right tool for the job" principle.
If the business problem is process-centric, say, a need to streamline or
optimize the policy issuance process, then implementing SOBAs as
compositions of Task Services will facilitate process flexibility. In
other cases, the business problem is more information-centric than
process-centric, for example, putting consolidated customer information
on a call center rep's screen. In such instances the architect's focus
may be on an Entity Service, because the rep is dealing with a
particular customer and must be able to interact with that customer in a
flexible way.

The big picture of the SOA architect's challenge, of course, is
delivering agility in the face of heterogeneity. On the one hand, the IT
shop contains a patchwork of legacy resources, and on the other hand,
the business requires increasingly agile processes. Understanding which
capabilities belong in Entity Services and which belong in Task Services
is a critical part of the best practice approach to SOA.

Reply via email to