reation of Web service applications is yet another complex task to add to the IT department’s list. Experience suggests it is not enough to approach Web services development armed with documentation on just the underlying technologies, such as SOAP and WSDL. Developers must also study the design issues and patterns related to the domain they intend to implement. For example, someone must decide whether to use RPC or document style encoding methods or whether asynchronous communication must be considered.
Without knowledge of patterns, the designer won’t apply these techniques, resulting in poor performance, poor scalability, and poor reliability, or the designer will reinvent the wheel, attempting to solve the problem with a new approach. Design patterns provide a set of reusable ideas that can speed up the design process because these ideas, as frameworks, can be leveraged.
There are several basic aspects of Web service design that, when mastered, make a successful project:
- Managing interoperability
- Understanding the lower-level transport models
- Providing the appropriate security
- Planning for deployment issues.
This article covers these basic design requirements and explores how well known design patterns can be applied to Web services. In fact, you’ll see that modeling a Web service can leverage much of the development techniques that you have employed with current software development technologies and languages.
Standards Improve Interoperability
A fundamental aspect of Web service design is interoperability. For a company’s Internet applications to be most effective, Web services must interface seamlessly internally and, potentially, externally with partners, suppliers, and customers. But, these entities may not have the same sophistication when developing their Web services, or they may have different XML representations of the same business data. With this in mind, interoperability must be designed into the architecture, not left up to chance.
If you’ve ventured into Web service development, you already know the building blocks for these services are SOAP (Simple Object Access Protocol), WSDL (Web service Description Language), and UDDI (Universal Description, Discovery and Integration). Figure 1 shows the relationship between these building blocks. This article will not cover the details of each of these technologies, but will delve into a few important characteristics that must be considered during Web service design. (See “Related Resources,” left, for links to other resources on the Web services building blocks.)
|Figure 1: Building Blocks. This graphic shows the relationship between SOAP, WSDL, and UDDI, the building blocks of Web services.
WSDL is the key to managing interoperability. It provides contracts for describing the interfaces to both new and existing applications. This allows multiple organizations to standardize on an interface to a service, without having to worry about the underlying implementation. Another benefit of using WSDL is that it is the focal point for many of the Web service tools on the market today. Most tools provide a way to automatically generate client code from an existing WSDL document. This can end up saving developers development effort because they don’t need to write any of the SOAP messaging code.
Of course, SOAP is the layer that implements messaging between Web service components. As such, SOAP should be a transparent interoperability technology. Unfortunately, many SOAP implementations vary from the standard by either creating extended features or by only making a subset of the functionality available. With different levels of SOAP support, it makes it difficult for true interoperability. Clients wanting to use Web services that run on different platforms have to be aware of these issues and code accordingly. If all vendors complied with the standards, the client wouldn’t have to be concerned about the underlying platform used.
Furthermore, interoperability between SOAP implementations can be difficult, as interpretations of the standard can diverge. But standards creation to resolve SOAP interoperability issues is being done by a number of working groups, such as SOAP Builders and WS-I. Today, however, developers are forced to create multiple variants of Web services to adequately interoperate with partners, which is expensive and labor intensive.
Also applicable to SOAP, specific Web services platforms may support an older version of a specification, which may not be interoperable with your clients. Choosing basic data types such as strings, integers, and standard array types can ease this problem, as the use of complex data types could limit what types of SOAP clients can talk with your service. Another best practice is to provide schema definitions for all data types. A schema definition provides a mechanism for defining the structure and content of an XML document.
Understanding Transport Models
SOAP is not a completely transparent solution, and Web service developers must look under the covers of SOAP, at the lower-level transport mechanisms and models to inspect how they are implemented. In the simple case, the platform will automatically generate the code and SOAP messaging constructs for you, making it easy to develop Web services. Generally, this works when the developer doesn’t have to do any customization of the service. When customization is required, often the developer works directly with the SOAP messages and possibly the XML content underneath. Thus, developers need to understand the SOAP and XML layers.
When designing your Web services interface, remember that the use of XML by itself does not guarantee interoperability. XML is not the “silver bullet” for solving integration problems. There is still a need for businesses to communicate and agree on the vocabulary that will be used in Web service interactions. Just introducing XML into your architecture won’t guarantee this. XML is simply a language or syntax for describing data. XML by itself does not provide the semantics for understanding the data. Spoken languages share many of same characters. However, an English speaker would not be able to understand text written in German. They share an alphabet (i.e., the syntax), but how the alphabet is interpreted (semantics) is different.
Even if you come to an agreement on meaning, it does not necessarily follow that you will share the same syntax, or language, with your partners. For example, you might decide that
DOM versus SAX
Many Web services runtime environments shield the developer from having to worry about lower-level XML parsing and processing. However, in situations where additional flexibility is required or where performance is critical, it might be important for the developer to write custom code or handlers that involve the processing of XML documents. In these instances, choosing between the two XML parsing models, DOM and SAX, will be a critical design decision (see Figure 2).
|Figure 2: DOM versus SAX. The graphic shows key differences between the two XML-parsing document models.
DOM uses a tree-like approach for accessing an XML document while SAX uses more of an event model. With a DOM parser, the XML document is converted into a tree containing the XML content. Subsequently, developers can traverse the DOM tree. There are a number of benefits to this approach. Generally, it is easier to program. A developer simply has to make one call to create the tree, and the navigation APIs are fairly easy to use. It’s also fairly easy to add and modify elements in the tree. A common use for DOM is when the XML document is being changed frequently by the service.
However, there are a number of disadvantages to using DOM. For one, when you parse an XML document using DOM, you have to parse the entire document. So, there is an up-front performance and memory hit in this approach, especially for very large XML documents.
SAX uses an event-based model for parsing XML. It works through a set of events that get fired as the XML is parsed. When a given tag is found, a callback method is invoked to indicate that this tag was found. Generally, the SAX approach reduces the overall memory overhead because it is left up to the developer to determine which events they want to handle. SAX can typically increase scalability if you are only processing subsets of the data. But, SAX is more difficult to program than DOM, and the SAX approach doesn’t work well if you are required to make multiple passes over the same document.
Generally, DOM is appropriate when you are dealing with more document-oriented XML files. SAX fits better when what you locate maps directly to other objects in your system (e.g., mapping from an XML structure to a Java class) or when you want to extract specific tags from your document.
Document Exchange vs. RPC models
One of the very first things that must be decided in your architecture is whether you will use RPC-encoded or document-style interactions. Your choice can impact the level of coupling present in your architecture.
An RPC (remote procedure call) is essentially a call to a remote method. Web services are XML-based, but you can still interact with the back-end service in an RPC-like fashion. Typically, the interaction is a very simple request/response, where the client sends a SOAP message that contains a call to a method. The application server receiving this request can then translate this request into the back-end object (e.g., a Java object, EJB method, or C# method). There is very little that developers have to do to build an RPC-based Web service because everything is mapped for them. Note that even in this approach XML is used to contain the call.
With document style, XML “business documents” are transmitted across the wire. They do not map directly to back-end method calls; they are actually complete, self-contained business documents. When the service receives the XML document, it might do some pre-processing on the document, perform some work, and construct the response back. There is usually no direct mapping to a back-end object. In fact, a request might invoke multiple components on the back end. The developer has to do much of the work in processing and mapping the XML data received, and there are very few tools on the market that can do this automatically. The document style is typically used in conjunction with asynchronous protocols to provide reliable, loosely coupled architectures.
A good analogy for illustrating RPC vs. document style is the difference between making a phone call and sending an email message. When making a phone call with no voicemail available, you are expecting some one on the other end to pick up and begin talking to you. This is very much a request-response paradigm and maps well to RPC-style messaging. On the other hand, sending an email doesn’t require the sender to be there. The email, or business document, which has all the information it needs, can wait in a queue or mail server until the receiver wants to read it. This is analogous to the document style interaction.
The general recommendation is to use document style messaging in your architectures. While an RPC approach can be implemented rather quickly, it will not be sufficient down the road when you have to interact with suppliers, customers, and partners who are beyond your control. In these situations, you will want an architecture that shields you (and the clients) as much as possible from the back-end implementation. Figure 3 shows the architectural differences between RPC and document style messaging.
|Figure 3: Document vs. RPC. Unlike document style messaging, RPC messaging requires an immediate response from the recipient.
Document style messaging delivers a number of benefits:
- With document style, you can utilize the full capabilities of XML to describe and validate a business document. With the RPC approach, the XML typically just describes the methods and parameters of the method call.
- It does not require a tight contract between the client and the service provider. RPC is typically static, requiring changes to the client when the method signature changes. With document style, the rules can be less rigid.
- Because it is self-contained, document style is typically better suited for asynchronous processing.
There is one key disadvantage to document style?it is typically more difficult to implement than an RPC approach. Despite this fact, the flexibility gains well outweigh the implementation costs. And more and more vendors are beginning to provide some support for the document style approach. Document style is also recommended over the RPC approach by organizations such as the WS-I.
Leveraging Well-Known Design Patterns
One area where Web service and object-oriented designs are comparable is in the use of patterns. In his book “Analysis Patterns” (Addison-Wesley), Martin Fowler defines a pattern as “an idea that has been useful in one practical context and will probably be useful in others.”
Patterns are good constructs for designing Web services. In particular, there are several well-known patterns that apply, such as can be found in “Core J2EE Patterns: Best Practices and Design Strategies” (Prentice Hall PTR).
- Adapter or Wrapper: Used to expose internal application functionality with a different interface
- Façade: Used to encapsulate complexity and provide coarse-grained services
- Proxy: Used as a surrogate for another object or service.
The Wrapper pattern leverages the popular Adapter pattern. The basic idea is to convert a component’s interface into another interface that the client expects. This would typically be used to provide some compatibility with the client. The adapter pattern can be used to expose existing technologies as Web services. For example, if you are running on a J2EE platform and have a need to interact with a C++ component, you may wrap the C++ component with JNI code, and then expose that Java interface as a Web service using the available Web services tools.
The Façade pattern is a familiar approach to building coarse-grained services. In J2EE, the Façade was represented by a session bean, while the fine-grained components were typically entity beans. For Web services, the same approach can be leveraged. The idea is to take existing components that are already exposed and encapsulate some of the complexity into high-level, coarse-grained services that meet the specific needs of the client. In using this approach, you can enhance overall performance of the Web services interactions and centralize infrastructure services such as security and transactions. Figure 4 shows the relationships between an application’s presentation and business tiers using the Façade pattern.
|Figure 4: The Fa