Web services combine the best aspects of component-based development with the Web's ubiquity and easy access. Think of Web services as black-box functionality you can reuse without worrying about how the service is implemented—a universal API, in other words. Whereas other middleware offerings limit access via binary, object model-specific protocols such as DCOM (Distributed Component Object Model) or RMI (Remote Method Invocation), Web services can be invoked via ubiquitous Web protocols such as HTTP and data formats such as XML.
Web services stem from three core standards: SOAP (Simple Object Access Protocol), UDDI (Universal Description, Discovery, and Integration), and WSDL (Web Services Description Language).
WSDL, an XML-based language, defines Web services and describes how to access them. The WSDL design view can also ease interoperability between disparate component middleware offerings. In this article, you'll learn how the WSDL specification offers a language-agnostic view of services, freeing developers from choosing the underlying implementation.
Note: To discuss this article, see Resources.
Middleware: A brief history
Web-enabled system designs traditionally employ a three-tier architecture composed of a client, a service, and data. While the service's position in this architecture has over time moved between the server and the client depending on available technology, today it firmly resides on the server. The 1990s witnessed an explosion of middleware solutions for the server platform, allowing a central position for business logic to manipulate back-end data.
For a whirlwind tour of middleware development, CORBA at the start of the 1990s represented the first platform-neutral, distributed middleware. CORBA purported to be language agnostic, exposing component interfaces as IDL (Interface Definition Language). Using a CORBA-compliant language, developers could remotely discover such interfaces' implementations on the network at runtime using a naming service to look up the component that implemented the interface. Although brilliant, only advanced programmers find CORBA suitable because they must worry around the underlying plumbing, such as transactions, concurrency, scalability, and component life-cycle management, forcing business functionality into second place.
Capitalizing on CORBA's shortcomings, in 1998 Sun Microsystems, in conjunction with other third-party middleware vendors, published the first Enterprise JavaBean (EJB) specification. EJBs introduced distributed components with session beans (components responsible for use cases and business logic), and entity beans (components to manage the data). Each bean describes its methods in remote interfaces, which the bean itself implements. EJBs also introduced containers, a place to deploy beans and manage their life cycle. In contrast to CORBA, containers handle the underlying plumbing, freeing the developer to code the business logic.
All that middleware development produced a myriad of legacy solutions—each requiring its own exotic protocol to access these components. (To be fair, CORBA and EJB are standardizing around IIOP (Internet Inter-ORB Protocol), although IIOP cannot be considered ubiquitous or pervasive.)
A fourth tier?
To let businesses expose their services, or an aggregation of their services, to other business and clients, interoperability and back-end integration of these legacy systems remains the work of costly computer consultants. When XML became a standard in 1998, it ushered in a new paradigm for distributed computing. Despite its hype, XML is simply a meta language—a language for describing other languages. XML for the first time let data be described in a standard way. Over the last three years, XML-related technologies have been standardizing with XSL (Extensible Stylesheet Language) to transform XML and XLL (XML Linking Language) to link it. Finally, when XML Schemas (a way to describe XML in terms of XML) became a standard this month, the final obstacle for XML's introduction into the middleware platform evaporated. XML now offers a way to describe services and data in a language-agnostic fashion.
Each of the aforementioned component architectures employ an interface to abstract a service description from how the service is implemented. That powerful object-oriented design pattern lets the implementation change while the offered services remain invariant to the change. However, these implementations remain specific to the distributed component architecture they describe: IDL to CORBA and remote interfaces to EJBs.
Describing these services with XML lets you future-proof them, not only in the implementation's terms, but also in terms of the underlying component architecture. Designing with XML moves away from the process-centric architecture ushered in by CORBA, towards a data-centric architecture. Data centricity lets businesses focus on what data moves around, not what process architecture processes the data.
The WSDL design view
As a core Web services technology, WSDL accomplishes that desired data centricity. Today, existing functionality can be described in terms of WSDL dialect, which future-proofs the application in relation to the implementing component architecture. The specific implementation (CORBA or EJB) is now described in terms of the general (XML and WSDL). WSDL will, in the future, become the design view, while component-specific stubs and skeleton implementations will be generated based on such WSDL. While Microsoft's .Net does not directly embrace the WSDL design view, that view is integral to the .Net framework. A WSDL file describing a service can still serve as a starting point to generate stubs and skeletons of any .Net implementation languages (C#, VB.Net, and C++).
Where and how then, can we realize the WSDL design view? A rich meta-model solution based on UML (Unified Modeling Language) allows you to graphically model anything from business processes to class relationships in an object-oriented (OO) model. You can also model UML as a meta object facility (MOF). That meta-meta model, a higher UML abstraction, can map to various implementations such as Java, CORBA, or IDL. Most importantly, a mapping exists between the MOF and XMI (meta data interchange).
Take modeling a "make-a-reservation" use case as a simple example. To make a reservation, something must enter the customer's information and reservation details. A UML analysis will ultimately conclude that a singleton object (there will only be one) must manage a customer reservation's persistence. In a UML model, the object is implementation agnostic. By mapping the object to XML, you could potentially produce the WSDL to act as a starting point for the stub and skeleton implementation generation. The important point: The modeling remains focused on the business process and delays its implementation in a particular component technology.
For a more complex example, think of aggregating existing and/or new services in a value-added, work-flow manner. Again, you could model such a system in UML, where the existing functionality, expressed in WSDL terms, could be imported into the UML modeling environment, and modeled in an aggregated manner, then exported again as WSDL. Such a just-in-time use case/service implementation represents a powerful asset in an ever-changing IT landscape in which technologies come and go and technologists most often follow. Businesses want to concentrate on these core competences rather than proclaiming themselves either as a J2EE (Java 2 Platform, Enterprise Edition) or .Net house with the resulting IT staff recruitment headaches and culture-building exercises.
The business drivers
With the dot-com industry's demise, new technologies face tougher adoption cycles. Gone are the days where technology is adopted for technology sake. With that in mind, we should begin this discussion by considering the business cases that make Web services adoption favorable. Before discussing such business cases, however, let's briefly recap component middleware solutions and the business cases they address.
Today, the programming world largely divides between two programming models: Microsoft's .Net and Sun's Java. While Java has long been the OO programming, Sun's dominance seems threatened by Microsoft's newly released .Net and its RAD (rapid application development) Visual Studio .Net tool. .Net features Web services native to the platform, while Java is at best trying to retrofit support using the Java APIs for XML. Although both platforms boast near-religious followings, most developers simply want the best tool for the job, such as using .Net on the client and EJBs on the server. To that end, Web services bring interoperability to that disparate arrangement.
Programming with WSDL as the design view lets you future-proof your system's implementation technologies. That verbose ASCII interface masks the component implementation, letting the programmer employ a best-of-breed approach that until now was the realm of exotic nonsupported APIs like JNI (Java Native Interface).
Analysis and design
Having examined the theory, the following is an example that begins with WSDL, then explains how you can generate component-specific stubs and skeletons from this WSDL file.
The example use case, which I first presented in "Add XML to Your J2EE Applications," (JavaWorld, February 2001) makes a reservation at a car rental agency (Figure 1).
To make a reservation, the system must persist a customer or retrieve an existing customer. That rudimentary analysis allows a first-cut sequence diagram, which includes a singleton Reservation Agent object to create and retrieve a customer and create a reservation. For scalability purposes, the singleton object is also stateless, with the client responsible for passing in state with each parameter call. The two repository objects, seen in Figure 2, represent persistence objects for the customer and the reservation objects.
In this example, we're interested in the customer data object passed while creating or retrieving a customer. The customer will possess an associated name, address, and credit card number. Because the car rental company operates globally, the system anticipates both US and UK customers by creating a base
Address object and two derived types:
UKAddress—standard polymorphic behavior where a person expecting a base
Address type can use either a
USAddress or a
UKAddress instead, as Figure 3 shows.
The reservation object proves much simpler. It contains only string attributes of a previously persisted customer name and his or her car type, start date, and end date. In a typical client/server distributed system, the
ReservationStateHolder and the
CustomerStateHolder objects pass across whatever wire protocol the distributed architecture supports. In the past these wire protocols (IIOP, DCOM, and so on) were all binary based, with IIOP as the only standards-based protocol. Because they are binary, you cannot watch as the data passes to the wire; however, with XML-based Web services, interoperability issues can easily be addressed via the readable nature of the wire protocol. I should also mention the Web services community's unprecedented success at rapidly consolidating interoperability.
The WSDL charter says:
"[WSDL is] an XML format for describing network services as a set of endpoints operating on messages containing either document-oriented or procedure-oriented information. The operations and messages are described abstractly, and then bound to a concrete network protocol and message format to define an endpoint. Related concrete endpoints are combined into abstract endpoints (services). WSDL is extensible to allow description of endpoints and their messages regardless of what message formats or network protocols are used to communicate."
WSDL can now describe these services in a verbose ACSII fashion independent of any implementation. You can produce such WSDL from a UML diagram (when UML tools begin to support this) or, as in this case, from existing code (a stateless session EJB remote interface) that has gone through a WSDL generator, which created the Reservation Agent's WSDL file. The WSDL file includes five sections, whose relationships you can see in Figure 4.
The WSDL document divides into two groups. The top group includes abstract definitions, while the bottom group consists of concrete descriptions. The abstract sections define SOAP messages in a language- and platform-independent manner. On the other hand, the concrete descriptions define site-specific matters such as serialization.
First, let's examine abstract definitions. There are three sections: