Service Gateway
Version 1.0.0
GotDotNet community for collaboration on this
pattern
Complete List of patterns & practices
Context
You are designing an enterprise application that consumes a
service provided by another application. The service defines a
contract that all service consumers must conform to in order to
access the service. The contract defines such things as the
technology, communications protocols, and message definitions needed
to communicate with the service. To communicate with the service,
your application needs to fulfill its responsibilities as detailed
in the contract.
Problem
How do you decouple the details of fulfilling the contract
responsibilities defined by the service from the rest of your
application?
Forces
When designing an application that consumes services provided by
other applications, you must address the following forces:
Implementing the consumer's contract responsibilities requires
you to implement security and communication mechanisms such as
authentication, marshaling, encryption, and message routing. These
mechanisms often change at a different rate and for different
reasons than the application's business logic.
The contract may specify data formats that are different from
your application's internal representation. If so, the data must be
translated. Sometimes this translation is a simple as renaming a
field or converting a data type, but other times this conversion
involves complex structural and semantic transformations. For
example, most services expose coarse-grained type-based interfaces
to optimize their use in distributed environments. Therefore, when
an operation is invoked on a service from an object-oriented
application, information from several of your applications'
fine-grained objects will often need to be aggregated and
transformed into the format specified by the contract. Likewise, the
response from the operation will usually need to be broken apart and
mapped back to fine-grained objects.
Your organization may not control the contract specified by the
service. If the contract changes, you will want to minimize the
impact on the application code.
The communications channel that provides connectivity between
your application and the services typically exposes a generic,
low-level application programming interface (API) to the
application. This API may include generic functions such as
SendData. In most situations, you want your application to deal
with a more semantically rich interface, through methods such as
ValidateCreditCard or GetCustomerAddress.
Some contracts may specify asynchronous messaging; that is, they
may not return a result immediately. Instead, the service consumer
must be prepared to receive a separate result message from the
service. The event-driven programming needed to handle such incoming
messages from a service can complicate an application significantly.
Solution
Encapsulate the code that implements the consumer portion of the
contract into its own Service Gateway component. Service
gateways play a similar role when accessing services as data access
components do for access to the application's database. They act as
proxies to other services, encapsulating the details of connecting
to the source and performing any necessary translation.
Service Gateway is a specific type of Martin Fowler's
Gateway pattern [Fowler03] that is adapted for use in
service-oriented architectures, and as such, its major concern is
encapsulating a consuming application's access to external systems.
Service Gateway often interacts with Remote Facade
[Fowler03] instead of interacting with an external system directly.
Remote Facade encapsulates complex functionality in provider
applications and exposes that functionality as a single simple
interface to consumer applications.
Service Interface is a specific type of Remote Facade
adapted for use in service-oriented architectures. In
service-oriented architectures, it is common for a consuming
application's service gateway to collaborate with a service
interface exposed by a provider application. The following fiqure
illustrates this relationship.
Figure 1: Service Gateway consuming the service of a
service interface
The Service Gateway component encapsulates the low-level
details of communicating with a service. Such details include but
are not limited to:
Communications channel. Service Gateway
encapsulates all the low-level network communications functionality
needed to communicate with the service. For example, Service
Gateway hides all the details of using SOAP over HTTP for
communicating with a Web service.
Data formats. Service Gateway maps between the
internal organization of information in your application and the
format mandated by the service's communication contract. For
example, your application may be composed of a collaborating set of
fine-grained objects; however a Web service it consumes may require
an XML document as input and provide an XML document as a result.
The gateway is responsible for translating between the fine-grained
object interfaces and XML documents.
Service discovery. For simple to moderately complex
scenarios, Service Gateway should encapsulate the process of
finding the proper service. This may involve looking up the
network address of the service in a configuration file or using a
service repository such as UDDI. For complex scenarios, such as
those that require dynamic determination of the proper service to
call based on changing data, the service discovery functionality may
be encapsulated in its own Service Gateway component.
Process adapter. Service Gateway should adapt the
application's business process to work with the service. For
example, a single call to the service gateway may result in multiple
invocations to one or more service operations. Therefore, the
interface that the service gateway presents to the application
should be in terms of the application's processes, rather than in
terms of communication and security protocols..
Asynchronous vs. synchronous calling semantics.
Service Gateway adapts the consuming application's calling
semantics (asynchronous or synchronous) to the calling semantics
specified by the contract. For instance, a consuming application's
design may not support the asynchronous calling semantics specified
in the contract. The consuming application's service gateway would
then be required to convert the application's synchronous calls to
the asynchronous protocol specified in the contract.
You do not have to implement Service Gateway as a single
object. In fact, it may be advantageous to separate some of the
functions into separate objects. For example, using separate objects
may make it easier to use code generation to create some portions of
the gateway. The code that implements the mapping data between the
internal application format and the format expected by the service
is an ideal candidate for this mapping, provided that the service
provider publishes metadata describing the required data format (for
example, in the form of WSDL or an XML schema). This metadata can be
used to generate a strongly typed class that encapsulates this
mapping.
Example
See
Implementing Service Gateway in .NET.
Testing Considerations
Service Gateway can significantly improve the testability
of the system. A service gateway encapsulates all the details of
accessing the service into a single component and hides the
component behind an interface that has no direct dependencies on the
underlying communications channel. This allows you to replace the
gateway with a Service Stub [Fowler03] during testing. This
stub does not access the external system at all, but returns results
that simulate the external system directly to the application logic.
Service Stub can also be used to simulate error conditions,
such as the external service being unavailable.
Resulting Context
Using a Service Gateway component to isolate the
application from the details of communicating with the service
provides the following benefits and liabilities:
Benefits
Decoupling the service access logic from the rest of the
application makes it easy to change the service the application
accesses. For example, you may want to switch to a new version of
the same service, or you may want to use a service with better
service-level guarantees from another vendor. Switching to another
service is much easier if you can automatically generate the code
that does the data mapping.
Service Gateway hides the complexities of accessing a
service from the application. This improves reuse of both the
application components and the service access components. The
application has no direct reference to the service, so it is
independent of any implementation details and the location of the
service. Encapsulating the service access logic in a separate layer
also improves the reuse of the access logic because it can now be
used across multiple service calls as long as the same transport and
authentication mechanism is used.
Service Gateway provides an ideal location for providing
common features such as asynchronous invocation, caching, and error
handling.
Liabilities
Service Gateway adds an additional level of complexity
that may be unnecessary for simple solutions. In particular, the
effort and infrastructure needed to support the automatic generation
of mapping components may not be needed if your organization will
only be accessing a few relatively static services.
A particular service gateway is responsible for interacting with
a single service. Coordination among multiple services must he
handled by an additional component such as the business process
component specified in
Three-Layered Services Application.
The service gateway is often contained within a single
application. Therefore, code duplication can result:if multiple
applications access the same service, both applications may
duplicate the gateway functionality. Developing a reusable service
gateway component is one alternative. Another solution is to extract
the common functionality into its own service that is deployed
locally within your organization. Some of distributed computing
solutions discussed in the previous chapter, such as Remote
Facade, can also be useful in this situation.
Related Patterns
For more information, see the following related patterns:
Three-Layered Services Application. The Service Gateway
component specified in Three-Layered Services Application is
an implementation of the Service Gateway pattern.
Service Interface. Service Interface plays a role
in provider applications that is similar to the role Service
Gateway plays in consumer applications.
Mapper [Fowler03].Mapper provides translation
between two or more fixed interfaces without either object being
aware of the other. Service gatewaysmay incorporate Mapper to
translate between application and service data formats.
Remote Facade [Fowler03]. Service Interface is a
specific type of Remote Facade adapted for use in
service-oriented architectures. A remote facade is similar to a
remote proxy but sometimes uses encapsulation to make the remote
interface more coarse-grained.
Gateway [Fowler03]. Gateway is an object that
encapsulates access to an external system or resource. Service
Gateway is a specific instance of Gateway.
Assembler: Similar to Mapper, this pattern
assembles an object from many objects. Communication between two
interfaces in a mapper is bidirectional, whereas it tends to be
unidirectional in assemblers.
Acknowledgments
[Fowler03] Fowler, Martin. Patterns of Enterprise Application
Architecture. Addison-Wesley, 2003.
[Schmidt00] Schmidt, Douglas, Pattern-Oriented Software
Architecture Vol.2, Wiley & Sons, 2000.
|