Software Design Patterns
Software Design Patterns
to Web
Services
From Objects
to Web Services
Web services have been put into practical use for many years. In this time,
developers and architects have encountered a number of recurring design chal-
lenges related to their usage. We have also learned that certain design
approaches work better than others to solve certain problems. This book is for
software developers and architects who are currently using web services or are
thinking about using them. The goal is to acquaint you with some of the most
common and fundamental web service design solutions and to help you deter-
mine when to use them. All of the concepts discussed here are derived from
real-life lessons. Proven design solutions will also be demonstrated through
code examples.
Service developers are confronted with a long list of questions.
• How do you create a service API, what are the common API styles, and
when should a particular style be used?
• How can clients and services communicate, and what are the foundations
for creating complex conversations in which multiple parties exchange
data over extended periods of time?
• What are the options for implementing service logic, and when should a
particular approach be used?
• How can clients become less coupled to the underlying systems used by a
service?
• How can information about a service be discovered?
• How can generic functions like authentication, validation, caching, and
logging be supported on the client or service?
1
2 C HAPTER 1 F ROM O BJECTS TO W EB S ERVICES
These are just a few of the questions that must be answered. This book will
help you find solutions that are appropriate for your situation.
In this chapter, you’ll learn what services are and how web services address
the shortcomings of their predecessors.
From Local
Objects to
Terminology Distributed
Objects
Web service developers often use different terms to refer to equivalent
roles. Unfortunately, this has caused a lot of confusion. The following
table is therefore provided for clarification and as a reference. The first
column lists names used to denote software processes that send requests
or trigger events. The second column contains terms for software func-
tions that respond or react to these requests and events. The terms appear-
ing under each column are therefore synonymous.
Client Service
Requestor Provider
Service consumer Service provider
This book uses the terms “client” and “service” because they are com-
mon to both SOAP/WSDL services and RESTful services.
Web services were conceived in large part to address the shortcomings of dis-
tributed-object technologies. It is therefore helpful to review some history in
order to appreciate the motivation for using web services.
From Local
Components were devised as a means to facilitate software reuse across dis-
Objects to parate programming languages (see Figure 1.1). The goal was to provide a
Distributed means whereby software units could be assembled into complex applications
Objects
much like electronic components are assembled to create circuit boards. Since
developers who use components cannot see or modify the internals of a compo-
nent, the form of reuse they offer is called black-box reuse. Components group
related objects into deployable binary software units that can be plugged into
applications. An entire industry for the Windows platform arose from this con-
cept in the 1990s as software vendors created ActiveX controls that could be
easily integrated into desktop and web-based applications. The stipulation was
that applications could not access the objects within components directly.
Instead, the applications were given binary interfaces that described the objects’
methods, properties, and events. These binary interfaces were often created
with platform-specific interface definition languages (IDLs) like the Microsoft
Interface Definition Language (MIDL), and clients that wished to use compo-
nents frequently had to run on the same computing platform.
Objects were eventually deployed to remote servers in an effort to share and
reuse the logic they encapsulated (see Figure 1.2). This meant that the memory
that was allocated for clients and distributed objects not only existed in sepa-
rate address spaces but also occurred on different machines. Like components,
distributed objects supported black-box reuse. Clients that wished to use dis-
tributed objects could leverage a number of remoting technologies like
CORBA, DCOM, Java Remote Method Invocation (RMI), and .NET Remot-
Customer
Object
*
Client
Address
Platform-Specific Object
Interface
Customer Component
From Local
Proxy Stub Objects to
Client Customer Object Distributed
Objects
ing. The compilation process for these technologies produced a binary library
that included a Remote Proxy [GoF]. This contained the logic required to com-
municate with the remote object. As long as the client and distributed object
used the same technologies, everything worked pretty well. However, these
technologies had some drawbacks. They were rather complex for developers to
implement, and the process used to serialize and deserialize objects was not
standardized across vendor implementations. This meant that clients and
objects created with different vendor toolkits often had problems talking to
each other. Additionally, distributed objects often communicated over TCP
ports that were not standardized across vendor implementations. More often
than not, the selected ports were blocked by firewalls. To remedy the situation,
IT administrators would configure the firewalls to permit traffic over the
required ports. In some cases, a large number of ports had to be opened. Since
hackers would have more network paths to exploit, network security was often
compromised. If traffic was already permitted through the port, then it was
often already provisioned for another purpose.
Distributed objects typically maintained state between client calls. This led to
a number of problems that hindered scalability.
In addition to these issues, if the process that maintained the client’s session
crashed, then the client’s “work-in-progress” would be lost.
Figure 1.3 Web services help to insulate clients from the logic used to fulfill their
requests. They establish a natural layer of indirection that makes it possible for
clients and domain entities (i.e., workflow logic, Table Modules, Domain Models
[POEAA], etc.) to evolve independently.
Web Service
time to time, and as a result, they may not be able to receive or process all
Considerations requests. Services may even crash while processing a request. Clients may crash
and too, in which case the service may have no way to return a response. Multiple
Alternatives
strategies must therefore be used to detect and handle partial failures.
In light of these inherent risks, developers and architects should first explore
the alternatives. In many cases, it may be better to create “service libraries”
(e.g., JARs, .NET assemblies) that can be imported, called, and executed from
within the client’s process. If the client and service have been created for differ-
ent platforms (e.g., Java, .NET), you may still use a variety of techniques that
enable disparate clients and services to collaborate from within the same pro-
cess. The client may, for example, be able to host the server’s runtime engine,
load the services into that environment, and invoke the target directly. To illus-
trate, a .NET client could host a Java Virtual Machine (JVM), load a Java
library into the JVM, and communicate with the target classes through the Java
Native Interface (JNI). You may also use third-party “bridging technologies.”
These options, however, can become quite complex and generally prolong the
client’s coupling to the service’s technologies.
Web services should therefore be reserved for situations in which out-of-pro-
cess and cross-machine calls “make sense.” Here are a few examples of when
this might occur.
• The client and service belong to different application domains and the
“service functions” cannot be easily imported into the client.
• The client is a complex business process that incorporates functions from
multiple application domains. The logical services are owned and man-
aged by different organizations and change at different rates.
• The divide between the client and server is natural. The client may, for
example, be a mobile or desktop application that uses common business
functions.
• MOM (e.g., MSMQ, WebSphere MQ, Apache ActiveMQ, etc.) can be used
to integrate applications. These technologies, however, are best reserved for
use within a secured environment, far behind the corporate firewall. Fur-
thermore, they require the adoption of an asynchronous communications
style that forces all parties to tackle several new design challenges. MOM
solutions often use proprietary technologies that are platform-specific. For
complete coverage of this topic, see Enterprise Integration Patterns:
S ERVICES AND THE P ROMISE OF L OOSE C OUPLING 9
Designing, Building, and Deploying Messaging Solutions [EIP]. Web ser- Services and
vices often forward requests to MOM. the Promise of
Loose
• A certain amount of overhead should be expected with HTTP due to the Coupling
time it takes for clients and servers to establish connections. This added
time may not be acceptable in certain high-performance/high-load scenar-
ios. A connectionless protocol like User Datagram Protocol (UDP) can be
a viable alternative for situations like these. The trade-off, however, is that
data may be lost, duplicated, or received out of order.
• Most web service frameworks can be configured to stream data. This helps
to minimize memory utilization on both the sender’s and receiver’s end
because data doesn’t have to be buffered. Response times are also minimized
because the receiver can consume the data as it arrives rather than having to
wait for the entire dataset to be transferred. However, this option is best
used for the transfer of large documents or messages rather than for real-
time delivery of large multimedia files like video and audio. For situa-
tions like these, protocols such as Real Time Streaming Protocol (RTSP,
www.ietf.org/rfc/rfc2326.txt), Real Time Transport Protocol (RTP, http://
tools.ietf.org/html/rfc3550), and Real Time Control Protocol (RTCP, http://
tools.ietf.org/html/rfc3605) are usually more appropriate than HTTP.
What about
incorrectly or is changed to produce results that are not in accordance
SOA? with the client’s expectations.
• Data structure coupling: Clients must understand the data structures that a
service receives and returns, the data types used in these structures, and the
character encodings (e.g., Unicode) used in messages. If a data structure pro-
vides links to related services, the client must know how to parse the struc-
ture for that information. The client may also need to know what HTTP
status codes the service returns. Service developers must be careful to refrain
from including platform-specific data types (e.g., dates) in data structures.
• Temporal coupling: A high degree of temporal coupling exists when a
request must be processed as soon as it’s received. The implication is that
the systems (e.g., databases, legacy or packaged applications, etc.) behind
the service must always be operational. Temporal coupling can be reduced
if the time at which a request is processed can be deferred. Web services
can achieve this outcome with the Request/Acknowledge pattern (59).
Temporal coupling is also high if the client must block and wait for a
response. Clients may use the Asynchronous Response Handler pattern
(184) to reduce this form of coupling.
• URI coupling: Clients are often tightly coupled to service URIs. That is,
they often either have a static URI for a service, or follow a simple set of
rules to construct a service URI. Unfortunately, this can make it difficult
for service owners to move or rename service URIs, or to adopt new pat-
terns for URI construction since actions like these would likely cause cli-
ents to break. The following patterns can help to reduce the client’s
coupling to the service’s URI and location: Linked Service (77), Service
Connector (168), Registry (220), and Virtual Service (222).
Service Oriented Architecture (SOA) is a paradigm for organizing and uti- Summary
lizing distributed capabilities that may be under the control of different
ownership domains. [OASIS Ref Model]
Summary
By eliminating coupling to specific computing platforms, web services have
helped us overcome one of the main impediments to software reuse. However,
there are many ways to go about designing services, and developers are con-
fronted with a long list of questions that must be resolved. This book will help
you find the solutions that are most appropriate for your situation.
This page intentionally left blank