This article is an excerpt from the new book Enterprise Java Programming with IBM WebSphere, Second Edition, by Kyle Brown, Gary Craig, David Pitt, Russell Stinehour, Mark Weitzel, Jim Amsden, Peter M. Jakab, and Daniel Berg, to be published by Addison-Wesley in November 2003.
In this chapter we'll cover some of the architectural challenges posed by Web Services, examine how to use (and not to use) Web Services, and see some best practices in applying Web Services for solving tough architectural problems. Web Services are the final piece of our Architectural Roadmap. You will see in this chapter how Web Services in WebSphere® usually use Stateless Session beans as their component implementation. The position of Web Services in our roadmap is shown below (Figure 34.1).
Figure 34.1. Architectural roadmap
There is a common set of emotions that go along with adopting any new technology. First, when you begin to hear the buzz about a technology, you start to think that it might be useful in solving your particular problems, and feel positively inclined toward it. As you learn more, your excitement grows - perhaps a short proof-of-concept is successful and leads you to jump in with both feet and adopt the new technology for a big new project. Then, the reality of the state of the technology begins to set in, and you start to find the limitations of the new technology. At this point, you might be able to muddle through and make the project successful despite the technology's limitations, or the project may crash around you amid a shattering of lost hopes and dreams. The old adage "all panaceas become poison" applies to most new technologies, and it applies no less to Web Services.
In the past two or three years since Web Services have started to be used in practical applications, a number of basic dos and don'ts have emerged about when Web Services are practical, and when they are not. Next, we'll examine some of these basic principles, and discuss some situations where disregarding them have made projects go awry.
Principle: Try not to use XML-based Web Services between the layers of a logical application.
Web Services function best where they complement other J2EE technologies, not replace them. For instance, a wonderful way to use Web Services is when connecting from an application client running out on the global internet to business logic written in EJBs inside WebSphere Application Server. Here you get a nice, clean separation of communication between the Controller and Domain layers of your application. This is the same place in which you would use EJBs and so, if you consider Web Services as another object distribution mechanism, then you can see why this would be appropriate. SOAP over HTTP can work in places where RMI over IIOP can't and so this allows the XML-based Web Services to complement the existing EJBs.
However, where people often go wrong with this is to assume that if this works between one pair of layers, it would work well between another. For instance, a common anti-pattern that we've seen far too often is a design where a persistence layer is wrapped inside an XML API and then placed in a process separate from the business logic that needs to invoke the persistence layer. In versions of this design, we've seen people actually serialize JavaTM objects into XML, send them over the network, deserialize them, perform a database query with the objects thus sent in as an argument, convert the database result set to XML, and then send the result set back across the network, only to be converted into Java objects and finally operated on. There are several major problems with this approach:
- Persistent objects should ALWAYS remain local to the business object that operates on them. The overhead of serialization and deserialization is something you want to avoid whenever possible.
- There is not yet a workable, fully-implemented transaction specification for Web Services. In EJBs with RMI-IIOP you have the option (although you are not required to) of including persistence operations in an outer transaction scope if you use Entity Beans or Session beans with Mapper objects if you so choose. If you introduce a layer of Web Services between the persistent objects and the business objects operating on them, then you lose that ability.
In general, XML Web Services aren't appropriate for fine grained interactions, even less so than RMI-IIOP. For instance, don't put it between the view layer and the controller layer of an application. The overhead of the parsing/XML generation and the garbage generation overhead will kill the performance of your overall application.
Principle: Be very careful when using Web Services between application servers
In many ways, interoperability between systems is the raison d'etre of Web Services. So, if you're connecting to a system written using Microsoft® .NET, then the use of Web Services is almost a given. While you could use other mechanisms like WebSphere Application Server's COM support, the best solution for interoperability going forward for both the Microsoft and IBM platforms is probably Web Services.
Sometimes it makes sense as when connecting disparate Java application servers from different vendors, but this is a less common occurrence. It is possible (for instance) to connect to EJBs written in WebSphere from a JBoss or WebLogic® server by using the WebSphere Thin Application Client. This would be a much better performing solution than one using HTTP and SOAP based Web Services. On the other hand, a more common occurrence is when you want asynchronous invocation of business logic written either in another application server or in some sort of legacy server. In this case, sending XML over JMS makes a lot of sense, and if you wrap your document-oriented XML in a SOAP envelope then it makes even more sense; you can take advantage of the header structure of SOAP and even possibly gain some out-of-the box features like WS-Security support.
Web Services have proven to be a useful approach for addressing some of the interesting problems of distributed objects. Since its introduction, SOAP over HTTP has become nearly the de facto standard for application-to-application communication over the Internet. With major web sites like UPS, Amazon and Google supporting the web services standards, this technology has become quite entrenched in the corporate I/T world.
However, when we look at using Web Services in an intranet environment, the issues are not quite as clearly defined as they are when discussing systems made available over the global Internet. Web Services provide a number of advantages when using them over the global Internet. For instance:
- Since the most common transport protocol for Web Services is HTTP, which is also the protocol that most of the Internet infrastructure is built around handling, managing, load-balancing, and allowing access to applications through HTTP is often much less troublesome than allowing access through other protocols. For instance, most corporations already employ a "DMZ" firewall policy that allows a set of protected servers to receive incoming traffic on HTTP or HTTPs but over no other protocols. This is rather an ironic situation; most businesses allow HTTP because it is believed to be a "safe" protocol for accessing web content. Now with Web Services, all sorts of business traffic can now flow through the corporate firewall. Simply assuming that because you web services traffic flows over HTTP that it is "safe" is inappropriate. You need to instead open a dialogue with your security organization on what business functions should be exposed over the internet, and what precautions should be taken to protect them.
- Web Services are quickly becoming ubiquitous. This is due to the curious historical occurrence that for the first time, both Microsoft and the Java industry have backed a single distributed technology. Since SOAP engines and tools that understand the basic protocols are now common, there is no requirement that a Web Services client be written using the same tool as a web services server. This enables communication between companies over the global Internet since business partners need not assume anything about the way in which either side of the conversation is implemented.
However, when we're considering a system in which the majority of users will be working within a corporate intranet, some of the following hurdles to overcome with Web Services and SOAP become more crucial. They are:
- First and foremost, we have found that with the current SOAP engines that there is literally an order-of-magnitude performance difference between Web Services calls and equivalent calls using the remote EJB protocol (RMI-IIOP). While a very large-grained approach with Web Services may be applicable to infrequent communication between business partners, using them in tightly coupled, high-volume internal applications is likely to be inappropriate. For instance, a call-center application where there are dozens or hundreds of requests per minute from each user, is probably not a good candidate for web services. In a situation like that the overhead of generating and parsing XML is problematic.
- Even though the industry is making progress with standardized authentication and authorization for Web Services, unfortunately most of the current set of J2EE products do not yet provide full support for this to the extent that they do for the J2EE protocols (like RMI-IIOP).
Looking forward into time, many of these problems could be addressed in a very elegant way by an expansion of the promised multi-protocol support for Web Services. For instance, if a standard RMI-IIOP binding for WSDL was available through JAX-RPC, then you could simply choose the right port for the job in your WSDL. However, pending standardization of this approach, these problems are still real issues.
So, since no one distribution approach solves all problems, what many organizations have concluded is that they need to support multiple distributed-object protocols and access mechanisms within their enterprise. A single application API may need to be available as an external Web Service using SOAP over HTTP, over RMI-IIOP for internal remote clients, using Local EJB references within an application server, and potentially even using SOAP over MQ for asynchronous interaction. There are two pieces to solving this puzzle; first, how do we provide access to business logic over multiple distribution protocols, and then what client programming model do we use to provide access to the remote business logic.
The second problem is actually the more interesting one, although we will need to discuss some approaches for the first one as well. In short, the solution to providing a common, unified client programming model that is independent of which of several different remote technologies are used can be found by applying an extension to the Business Delegate pattern from [Alur].
Business Delegate is a pattern that allows a client to remain ignorant of the implementation details of a particular remote business service. The participants of the pattern are shown in Figure 34.2 (adapted from [Alur]).
Figure 34.2. Business Delegate Participants
The key here is that you have a client that needs to use a remote business service. The Business Delegate hides the implementation details of how to obtain the business service and invoke its methods by providing an external API that is nearly the same as that of the Business Service, minus the details of things like Remote Exception handling. It does so by delegating the details of object lookup to a lookup service (usually implemented as a Service Locator from [Alur]) and by handling Remote Exceptions (as well as other issues like retry) inside the methods of the Business Delegate itself.
Now, in the previous diagram you should carefully note the "uses" relationship between the delegate and the Business Service represents a set of remote calls. That is the key to this pattern. As [Alur] states on p 249, "The main benefit is hiding the details of the underlying service. " An explicit consequence of this pattern (discussed on p. 255 of [Alur]) is to hide remoteness of the business service. In fact, the pattern contains the seeds of more than just hiding remoteness. By providing a purely local mechanism for accessing a remote object, it hides the underlying remote protocol used so that (with only a slight modification to the pattern) you can allow the client to choose from several different remote protocols.
The problem is that when most J2EE developers think of the Business delegate pattern, they only think of it in terms of Remote EJB access. The code examples in [Alur] only show this application of the pattern, and the vast majority of the text in the pattern itself also only refers to using it with EJBs. However, the pattern is not limited to EJBs alone. Consider using a Web Service through the JAX-RPC API. The same issues that led to the use of this pattern for EJBs (e.g. the need to know how to obtain the remote object reference, and the need to know how to handle remote exceptions and retry logic) apply for Web Services as well. What's more, the pattern also provides a useful way to abstract away the details of the differences between Local and Remote Interfaces in EJB 2.0 - rather than having to make your application programmers explicitly pick which Home interface (remote or local) and which of the local or remote interface to use, you can abstract that detail away by hiding the decision behind a set of two Business Delegates.
What we are arriving at is a slight modification of the pattern where we explicitly recognize that there are several different Business Delegate implementations that might apply to a single Business Service, each depending upon the particular access mechanism that is needed for a specific circumstance. We can make this explicit by introducing another couple of elements into the pattern. First, we have to decide that there needs to be a specific interface that defines the methods of the Business Delegate itself. Each of the different business delegate implementations (for Web Services, Remote EJB access, Local EJB access, etc.) must implement the delegate interface. Second, we need to provide a mechanism for allowing clients to create the particular Business Delegate implementation that is needed. The most common solution to this is to create a Factory that can (based on a set of input parameters, or a set of configuration parameters pre-set in the class) create one of many different implementations of the Business Delegate interface. The result of applying these two changes can be seen below in Figure 34.3.
Figure 34.3. Business Delegates with Factory and Interface
Now, astute observers may note that this does remove one of benefits of the Business Delegate pattern - the original pattern kept the client from having to use a Factory (in this case, the EJBHome) to create an object (the EJB reference), while we have reintroduced a factory into the mix. This slight complication to the programming model is well worth the benefits that it conveys, however. What we have done is to replace multiple factories (such as the EJBHome and the JAX-RPC Service) with a single factory that returns a local Business Delegate adapted for a specific distribution protocol.
What this design allows you to do is to take advantage of each of the available protocols without having to have your client depend on the specifics of which protocol is being used. So, let's consider the case where you have an application client that can run both inside and outside your corporate firewall. By setting a configuration parameter for the factory, the same code could used in both situations; inside the firewall you could choose RMI/IIOP while outside you could choose SOAP over HTTP. What's more, if the code that communicated with the remote object was part of a larger business component, then that component could also be incorporated into a Servlet or JSP by configuring the parameter to instruct the factory to use a Local EJB reference instead. So, our final configuration might look like Figure 34.4: Multiple delegates and servers.
Figure 34.4. Multiple delegates and servers
In fact, this pattern could be extended to any number of additional protocols, so long as those protocols maintain the same basic RPC semantics. Of course, the qualities of service may differ for each protocol. For instance, transactions (at least today) will not flow over a SOAP/HTTP invocation, while they will over an RMI-IIOP invocation. There are also subtleties of security to consider. However, for many situations, these differences are irrelevant and the pattern provides great value.
A final note about this pattern is that it provides value to you specifically on the client side only for the particular language in which you implement your business delegates. So if you, for instance, implemented a business delegate framework in Java that allowed you to connect transparently over either RMI-IIOP or SOAP/HTTP, it would not help you at all if your Web Services clients could be written in C#.
You would think that a pattern that (in retrospect) is as obvious as this one would have managed to find its way into one or more open-source projects or commercial products. In fact, that has happened, although it has appeared to have "slipped under the radar screen" of most developers. In 2002 IBM donated a technology called WSIF (the Web Services Invocation Framework) to the Apache consortium. WSIF is described (on the WSIF home page at apache.org) as "...a simple Java API for invoking Web services, no matter how or where the services are provided." The key difference here is that WSIF is designed around using WSDL as a "normalized description" of a piece of software using a protocol. If you have a WSDL document with different bindings for a set of technologies (such as SOAP over HTTP or EJBs) then you could use WSIF providers to connect to remote objects implemented using different distribution technologies.
WSIF is primarily used through an API whose constructs closely match those of WSDL. However, it is possible for tools to develop Proxy classes that use the WSIF API in such a way that the external API of the Proxy matches the equivalent Java definition of a WSDL-described Web Service using the JAX-RPC mappings. Some IBM tools (like WebSphere Studio Application Developer - Integration Edition) can generate proxy classes like this to provide a simple Java interface to the WSIF API in some cases. So, in the case of a JCA interface built using WebSphere Studio Application Developer - Integration Edition, a Proxy class (in effect, a Business Delegate) can be generated on top of the WSIF API, which would then call into a JCA WSIF provider. So, WSIF provides one way to handle what is needed on the left-hand side of the diagram, but only if the entire system is described with WSDL and you have (or can write) all of the appropriate providers.
One final word on WSIF for those who are interested in using it; while WSIF is an intriguing technology, and can be a useful approach for many users, you should remember that it is an open-source technology now, and not one that has been standardized as part of the JAX-RPC specification. In the future, we expect JAX-RPC to evolve to take on the same multi-protocol capabilities that WSIF has - at this point the WSIF APIs will prove to be more of a liability than a help. So, while WSIF may be used as a point solution, you should be cognizant of the future of the approach. While IBM uses WSIF internally in its own products extensively, it should probably not be viewed as an accepted standard Web Services API - for your own implementations you should stick with JAX-RPC and other fully standardized APIs.
In Chapter 32 you about learned the basic outlines of the approach which IBM has christened the Services Oriented Architecture (or SOA). Probably the most difficult portion in developing a Services Oriented Architecture lies in determining what the right level of granularity of a Web Service should be. To a large extent, this consists of determining what constitutes a good Web Service, and what does not. Earlier in the chapter we've seen some appropriate uses of Web Services technology as a mechanism for communicating between disparate system types (such as servers written in .NET and servers written for WebSphere) and as a way to facilitate client-server communication over the Internet. But Web Services is a much broader approach than just these two canonical examples. In the following sections we'll talk about some appropriate uses of Web Services that might help you better understand where in your designs to apply the technology.
Back in Chapter 30 we discussed some best practices around the use of Session EJBs and tips in applying the Session FaÐ·ade pattern. One of the things we discussed was that a good level of granularity for a Session FaÐ·ade is at the Service level - this means that you identify a logical service provided to a common group of clients and then create a Session FaÐ·ade at that level.
What you are doing is, in effect, creating a unified logical view on a subsystem. This "large-grained" session faÐ·ade is especially appropriate when you consider how to use Web Services. First, for efficiencies sake you would not want to have a fine-grained, "chatty" interface to a Web Service anyway. As we have discussed earlier, the overhead involved in XML parsing and generation would take a flaw that would be noticeable in an EJB design and then magnify it. So, you would look for as few methods as possible to represent the whole scope of your subsystem's function, and then work on making the methods large-grained, so that each method does one complete logical function.
As an example, consider if you were building a system to run an e-commerce site on the Internet. You can readily imagine the different subsystems that would be needed based on the parts of the domain; Order Processing, Shipping and Shipment Tracking, Returns, and Inventory Management come to mind fairly quickly. This would be exactly the level of component that would be appropriate as a Web Service - by presenting a single logical view of the entire subsystem, clients would be protected from knowing both the details of how the subsystem is implemented, and also isolated from changes in the implementation of the subsystem over time.
Another common theme we have seen in many Web Services designs is the need to represent several different implementations of a particular component, where you need to be able to both isolate requestors from change in the implementation and also provide access to many different "flavors" of that component, either at once or over time.
For example, consider the following problem. Let's say you're building a web site that will provide customers with Insurance quotes. To do so you have an agreement with several different Insurance companies to provide you with quotes. But you have a problem; each of the Insurance companies has a different mechanism for accepting quote requests and providing quotes to you. How do you design you web site to deal with this?
In a nutshell, this is the place where the Adapter pattern from [Gamma] can come to your rescue. Consider the following design (Figure 34.5):
Figure 34.5. Insurance Broker design
What you could write is a Broker component that would do two things; look in a local UDDI repository for the references to different Adapters that implemented a particular WSDL interface, and then use that common WSDL interface to get quotes from all of the insurers by sending the same getQuote request to all of the adapters. Each insurer-specific adapter (which you would be responsible for writing) would translate the Web Services request into a request that the Insurer's own Quote system could understand. There could be several ways of doing this:
- The easiest way (a no-op) is to simply have the Insurer implement the WSDL document describing the getQuote interface themselves! In this case you don't need an adapter at all, and you simply pass through the request. However, it may be useful even to have a simple adapter in this case - you might want to log outgoing requests, or translate from one protocol (say HTTP) to another (like HTTPs). This sort of intermediation is the function of a component of WebSphere Application Server, Network Deployment called the Web Services Gateway. It allows you to set up filters that can perform logging, protocol translation, or a number of other useful features. You can even write your own filters for deployment in the gateway as well.
- If your business partners won't implement your WSDL, but provide you with a document type that is similar, then you might be able to write an adapter that could transform from their existing format into your format. For instance, they may provide you with an existing system that you can access through HTTP to a quote presented as an XML document in their own unique, proprietary format. In this case, you could write a Web Service that uses an XSLT document to transform from their XML format into the format your WSDL document specifies.
- Finally, if you have access to existing business logic through a standard J2EE protocol (like JMS over WebSphere MQ, or JCA with IBM CICS) then you can write a Web Service as an EJB or Java Bean that uses that protocol and the appropriate JCA, JDBC or JMS connectors to send the request on to the target system, get back the quote, and then translate the response into the format you need. Here you could use the WSDL2Java tool to generate a simple skeleton for you to fill out with the appropriate translation logic
The great thing about this approach is that your Broker system is now completely independent of the individual Insurers - adding another insurer could be as simple as implementing a new Adapter and then registering that Adapter to the UDDI repository. Likewise, changes to the implementation of the Adapter (if, for instance, one of your Insurers decides to implement their own compliant Web Service after you have been using an Adapter written for CICS) do not affect the Broker at all. The Web client software would simply ask the Broker for quotes for a particular set of circumstances, and then present the results back to the user.
Finally, you need to ask yourself if you have a need to take parts of your system and then compose it into a larger system in a configurable way. In other words, do you need to implement one or more workflows that use the different parts of your system? A workflow is a way of describing a set of steps (often called activities) that are combined to execute a particular business process. For instance, in the Insurance industry, there are a number of steps that make up paying a claim. If you imagine that each of these steps are implemented as individual Web Services, then the process of paying the claim will consist of invoking the different services in a particular order, perhaps with some services being skipped or bypassed depending upon the results of previous service invocations.
In 2002 a specification was released by IBM, BEA® and Microsoft called BPEL4WS (The Business Process Execution Language for Web Services) that describes how to compose Web Services into workflows, and thus form larger, composite Web Services. You should note that this does not necessarily mean Web Services using SOAP over HTTP - this includes all WSDL-defined Services, which could include EJBs using RMI-IIOP. BPEL4WS features the following capabilities:
- A mechanism for specifying tasks (Web Services) and transitions between tasks
- The ability to support either "Micro-flows" (flows that occur within an atomic transaction, such as within a single EJB invocation) or "Macro-flows" (flows that span several transactions, and may span large periods of time).
- A simple mechanism for specifying conditional execution and task selection
- A sophisticated error handling mechanism that includes handling of compensating transactions in cases where a workflow must be "rolled back" to a specific point.
A Workflow system consists of two parts; a workflow specification tool and a workflow execution engine. The advantage of using a standard specification language like BPEL4WS between the two is that it allows both to become pluggable over time. IBM has a very sophisticated Workflow specification and optimization tool called the WebSphere Business Integration Modeler (formerly known as HoloSofx). By mid-late 2003 this tool will fully support BPEL4WS. Currently, IBM WebSphere Application Server Enterprise Edition supports a predecessor of BPEL4WS called WSFL (the Web Services Flow Language) but it will be updated with BPEL4WS capabilities by late 2003 as well. There are also Workflow specification tools that are part of IBM WebSphere Studio Application Developer, Integration Edition that will be updated to work with the BPEL4WS-compliant version of the WebSphere Business Process Choreographer.
Interoperability between Web Services Providers and Web Services Requestors written in different languages, or using different tool sets has been the prime example of the benefits that Web Services can convey. In fact, it's probably the only reason why they are so popular. Let's face it; the IT industry is divided into two warring camps, the Microsoft camp and the Java camp, and anything that can be done to call a truce between those camps must be considered to be a good thing. In real-world situations, having some way to call code written using one technology from the other is extremely useful. It can allow systems from different organizations within the same company to communicate for the first time (not an uncommon event given the rapid rate of corporate mergers) and can allow companies to work with business partners that use a different set of technologies. However, even though the promise of interoperability is the major reason why we're looking at Web Services, the reality is that interoperability doesn't come for free. You have to work at it and design it in to your systems from the beginning, just like you have to design in scalability, performance, reliability and security.
Luckily for developers, some order has begun to emerge out of the chaos of spec interpretation through the action of an organization called the WS-I (Web Services Interoperability Organization) which is an industry consortium with a charter to promote interoperability among Web Services vendors. WS-I will produce recommendations and tools for tool vendors and developers to use to ensure interoperability of Web Services. One of the first, and most crucial, specifications produced by the WS-I is the WS-I Basic Profile, which describes a subset of the ways in which the four main Web Services specifications (WSDL, SOAP, HTTP and UDDI) can be used to ensure interoperability. While most of the recommendations in the WS-I Basic Profile deal with issues that are of interest only to the vendors of Web Services toolkits, there are some steps that you must take to ensure that your Web Services are in compliance with the WS-I Basic profile, and ensure that they Web Services are interoperable. In particular, there are two issues in the WSDL (and also the SOAP) spec that come into play here. These two issues are encoding style and binding Style.
The SOAP Specification specifies a mode called "encodingStyle" that can take on two values, "encoded" and "literal" . This refers to how the XML representing parameters is defined on the wire. Encoded refers to Section-5 of the SOAP specification, which defines a primitive mechanism for mapping programming language types to XML. "Literal" means don't do that. Instead, the type information is provided by an external mechanism, more likely than not a WSDL document that uses XML schema to define exactly what types are used in the SOAP message.
The reason this came about is because the SOAP specification was written prior to the adoption of the XML Schema specification. Thus, the original SOAP specification had to provide a way of encoding type information along with the parameters being sent for method calls because there was no accepted way of specifying it. Where this really differs from XML Schema is with Arrays. Section 5.4.2 of the SOAP specification specifies a particular mechanism for representing programming language arrays in XML that uses a special SOAPEnc:Array schema type. Also, encoding information (such as <item xsi:type="xsd:string">) was usually associated with SOAP message body elements encoded using the SOAP Encoding standard.
However, since the adoption of XML Schema (which you'll remember, WSDL uses to represent its types), most languages have rendered the need for SOAP encoding obsolete by specifying their own mappings (or serialization rules) from XML schema to the programming language types. For instance, the JAX-RPC specification uniquely specifies how Java types are mapped to XML Schema elements and vice-versa. This obviates the need for extra encoding information in the XML. So, as a result, SOAP Encoding is no longer favored, and has been superceded by literal encoding with the mapping being specified externally by an XML Schema document, usually in the form of a WSDL document.
So, as a result, you should not plan on making your Web Services use SOAP Encoding if interoperability is ever likely to be required. You should plan on using literal encoding instead, whenever possible. Most of the interoperability problems that have been encountered by developers using Web Services stem from differing interpretations of SOAP encoding, so avoiding the issue altogether is a useful tactic. In fact, the WS-I has gone so far as to specifically exclude the use of SOAP encoding from their basic interoperability profile .
Now it is time to discuss the other issue, which is binding Style. The WSDL Specification specifies two different "binding styles" in its SOAP binding. The values of the binding style attribute are "RPC" and "Document". What this means is that if a WSDL document specifies an operation has a binding style attribute set to "RPC" then the receiver must interpret that message using the rules found in Section 7 of the SOAP specification. This means, for instance, that the XML element inside the SOAP body (called a "wrapper element") must have a name identical to the name of the corresponding programming-language operation that is to be invoked. Each message part within that element must correspond exactly (in name and order) to a parameter of that programming-language operation. Finally, there must be only a single element returned (which must be named XXXResponse, where XXX is the name of the corresponding operation in the language) that contains inside it exactly one element, that is the return value of the operation.
The "Document" binding style is looser. A message in the document binding style must simply be made up of well-formed, namespace-qualified XML. It is up to the SOAP engine that receives it to determine how to interpret it. Now, having said that, it is common (for instance among Microsoft tools) to use "Document" binding style and "Literal" encoding to represent RPC's. In that case, the sender will still follow many or all of the rules of Section 7 of the SOAP spec in formulating the message, but it is up to the receiver to determine how to handle the message, either as an RPC call or as a document to be processed. In particular, there is still an outer element that represents (and names) the operation, while that element contains elements that represent message parameters.
Perhaps the most curious dichotomy to emerge in the Web Services design community has been the conflict arising from those who approach Web Services from a messaging background, and those who approach it from an object-oriented programming background. [Sun] typifies this dichotomy when they make a mistaken distinction between document oriented web services and RPC style web services. They state that document oriented web services applying only to asynchronous messaging processing while RPC style web services apply to synchronous services. They are missing a valuable point; the question of how the choice of a usage scenario applies to the binding style. To understand this, let's examine the three Usage Scenarios defined in the WS-I usage scenarios). They are:
- One-way - a One-way message is one that does not require a response from a Web Services provider. The Web Services Consumer issues a request to a provider, but then does not wait for a response. This was defined in [WSDL] and has been clarified in [WS-I].
- Synchronous request/response - This is the most commonly used scenario, which consists of a Web Services consumer issuing a request to a provider, and then synchronously waits (blocks) while the provider processes the request and then provides a response. This is the operating semantic that all remote procedure call (RPC) mechanism implement since this is the standard function-call semantic in procedural and object-oriented programming languages.
- Basic Callback - The basic callback scenario combines two synchronous request-response scenarios to enable asynchronous processing. An initial request is issued to a provider containing information that identifies the receiver. The request immediately results in an acknowledgement of receipt from the provider (without returning a value to the receiver). At some point in the future, the receiver would then issue a request to the initial receiver (the "callback") providing it with the full set of information requested by the initial request; the response to this request will be another acknowledgement. The two interactions are tied together by a Correlation Identifier ([Hohpe]).
A key point to derive from this is that RPC style web services are simply a subset of document-style services in general. While a document style service can be used in any of the three usage scenarios defined in WS-I, an RPC-style web service is limited to only the synchronous request/response scenario. The more important point is that if you choose to use document-style messages across the board, they will work regardless of the usage scenario you choose. There are some distinct advantages to taking this approach, namely that a single set of design principles can guide you regardless of the usage. This results in systems that are more consistent and more easily maintained
Despite the architectural arguments for or against using document style across the board, the fact is that the WS-I has declared that both RPC-Literal and Document-Literal style Web Services are allowable for interoperability. In particular, you need to evaluate whether to use document style or RPC style messaging in your web services based on the details of the particular scenario you are implementing. While you want to be consistent in your processing model, you can achieve this by using either document and RPC style in a consistent way. You do not have to choose just one style throughout your business.
Some guidelines that can help you identify which mode to use in a particular scenario are:
- Some XML is intended to be treated as documents (for instance, consider a newsfeed). Document style should be used when the message payload is going to be processed as XML, for example, when it is to be transformed into another format and stored directly into a database or if the payload is going to be merged with other XML and then sent on to another destination.
- If your application already has XML interfaces, you will probably want to use document style. Likewise, if you are sending data conforming to an industry XML vocabulary, you will probably to want to use document style.
- When executing functions or sending data which will be analyzed, you need to carefully evaluate the choice between document and. RPC offers simplicity and sometimes better tooling support. Document offers greater flexibility and decoupling, and under some circumstances (large messages with many elements) vast reduction in message size, but may requires more XML expertise and hand coding.
However, despite that fact that both models have been accepted, the practical fact of the matter is that there have been fewer problems found when using document-literal style communications than RPC style. Thus, if you anticipate any interoperability with your services, we would strongly advocate that you plan on using the document-literal style for your Web Services. When doing so, be very cognizant of the limitations placed on what XML Schema elements can be understood by JAX-RPC and other vendor tool sets.
Interoperability between different systems is one of the primary reasons for using Web Services. However, you can't just assume that your Web Services will be interoperable, even if you do follow the procedures we've discussed above; you need to test your services to ensure interoperability. Our recommendation is to plan to simultaneously test your services with as many different clients as you anticipate will use your services. For instance, we would recommend that nearly all services be tested against both Java and .NET clients. This is critical to avoid being unpleasantly surprised later. Also, you should make sure that you keep abreast of the latest interoperability issues that have been found. Use WS-I.org and soapbuilders.org as resources for discovering these issues.
While Web Services are not the solution to all problems, they can certainly make some problems, notably problems of cross-language or cross-system integration easier. In this chapter, you've seen a bit more about how a Services Oriented Architecture can help you obtain these benefits, and how to design your systems to both make interoperability easier and to make it possible to take advantage of the best communication mechanism available for each service. In particular, you've learned the following major points:
- Web Services are not appropriate for all situations. They are quite effective at solving different types of interoperability questions (interoperability with Microsoft tools, connecting with existing web-services enabled systems, or when dealing with firewall issues) but are not as effective in many designs where both sides of a conversation can be mandated.
- Plan on using the Business Delegate pattern to allow for different situations where clients may choose different transports based on differing quality of service needs.
- When planning to use Web Services, you should be cognizant of the differences between Microsoft and Java tools with regard to processing style. We recommend the use of document-literal Web services wherever interoperability is a possibility.
- Enterprise Java Programming with IBM WebSphere, Second Edition, by Kyle Brown, Gary Craig, David Pitt, Russell Stinehour, Mark Weitzel,
Jim Amsden, Peter M. Jakab, and Daniel Berg. Addison-Wesley, November 2003
Kyle Brown is a Senior Technical Staff Member with IBM Software Services for WebSphere. Kyle provides consulting services, education, and mentoring on object-oriented topics and J2EE technologies to Fortune 500 clients. He is a co-author of Enterprise Java Programming with IBM WebSphere, the WebSphere AEs 4.0 Workbook for Enterprise Java Beans, 3rd Edition, and The Design Patterns Smalltalk Companion. He is also a frequent conference speaker on the topics of Enterprise Java, OO design, and design patterns. You may contact Kyle at email@example.com.
Rachel Reinitz is a Senior Certified IT Specialist with IBM Software Services for WebSphere focusing on Web Services. Rachel consults with customers and ISVs on how Service Oriented Architecture and Web services can be used to achieve their business and technical objectives. Rachel can be reached at firstname.lastname@example.org.