Web services development patterns

Which approach is best for you?

Web services have become a standard way of implementing Service Oriented Architectures. Developers have used many patterns of developing these Web services, but these patterns have not been well-defined or discussed. This article describes these development patterns and discusses their advantages and disadvantages in terms of tooling support and results. The analysis is based on real-world experience in developing customer solutions.

Greg Flurry (flurry@us.ibm.com), Senior Technical Staff Member, IBM India Software Lab Services and Solutions

Greg Flurry photoGreg Flurry is a Senior Technical Staff Member in IBM's SOA Advanced Technology group. His responsibilities include working with customers on service-oriented solutions and advancing IBM's service-oriented products. If you have comments for the Greg about this article, send them to wsdd@us.ibm.com.


developerWorks Professional author
        level

Manish Modh (manish@us.ibm.com), Senior Solutions Engineer, EMC

Manish ModhManish Modh is a Senior Solutions Engineer in IBM's Enterprise Integration Solutions group. His responsibilities include working with customers on service-oriented solutions and advancing IBM's service-oriented products.



02 November 2005

Introduction

Web services provide a standard way to implement a business function that can be invoked remotely. They support interoperability by separating the mechanisms of access from the implementation. For this reason, Web services are the de facto standard for implementing an SOA that requires a loose coupling between a requester and a provider. The development tools industry quickly jumped onto the Web services bandwagon and provided mechanisms for developing Web services. These mechanisms can now be formalized into a set of development patterns for Web services. Each of these patterns has advantages and disadvantages that determine which pattern should be used in a given situation.

This article assumes that you have a general familiarity with Web services concepts and standards. The implementation platform used in this article is Java™, and the article also assumes familiarity with Web services and JAX-RPC, which are a pair of specifications from the Java Community Process. JAX-RPC defines the deploy-time and run-time requirements for a deployable, executable Web service in the Java 2 Enterprise Edition (J2EE) platform. Examples of these artifacts include the Web Services Definition Language (WSDL) document and the webservices.xml file that assists deployment. While less complex, JAX-RPC also defines a set of artifacts on the requester side, including a webservicesclient.xml file for defining client-side behavior. Although the article focuses on the Java platform, the patterns described in the article apply equally to any platform that supports Web Services development, such as .NET.

One of the major tenets of an SOA is publish, find, and bind. This tenet recognizes that the key to any Web services development is the WSDL document that defines the interface and binding of the corresponding Web service implementations. The WSDL document defines the contract between the Web service requester and provider such that the implementation details (and even implementation platform) of each can be different and can change without any impact on the others.

A WSDL document has several aspects relevant to this discussion. The most relevant are the types and the portType elements. The types element defines the XML schema for the data types used in the interface; these types may be explicitly defined in the WSDL and/or imported from other XML schema files. The portType element identifies the set of operations offered by the Web service, via a set of operation elements. Each operation element in turn references (indirectly through message elements) the data types defined in the types element for use as input and output parameters.

Since a WSDL document is so important, the development patterns described in this article center around how WSDL documents are created and manipulated. Once a WSDL document is created, you can use Web service development tools to help you generate the necessary deploy-time and run-time artifacts defined by JAX-RPC. Keep in mind that the WSDL document is the key to Web services development -- this article considers WSDL the top level of development because it is a meta-language that describes an interface in abstract, implementation-independent terms. Code is considered the bottom level of development because it can be mostly generated, deployed and executed. Given this terminology, this article identifies and describes three development patterns:

  • Bottom-up pattern: Start with Java to produce WSDL.
  • Top-down pattern: Start with WSDL to produce Java.
  • Round-trip pattern: Start with WSDL to produce Java, which is then used to produce WSDL, which is then used to produce Java.

These patterns are described in the following sections, including the advantages and disadvantages of each. The advantages and disadvantages are derived from experience in developing actual customer solutions involving business integration and modernization.


Bottom-up development

The first generation of Web services tools for Java was targeted at exposing existing code as Web services. This approach is called bottom-up because the starting point is code that is being abstracted into an interface definition and subsequently exposed as a Web service implementing that interface. This pattern is familiar to many Web services practitioners and is well-supported by even the latest generations of Web services tools. The bottom-up development pattern encompasses the following development steps, illustrated in Figure 1:

  1. Identify or create JavaBeans that represent the data types of the input and output parameters of a service interface. These can be existing or new JavaBeans. Because these JavaBeans are used to transfer data to and from the service, they are sometimes termed Data Transfer Objects (DTOs). Note that only the attributes that follow the JavaBean pattern (such attributes have a getter method and a setter method) are exposed in the Web service interface. You can use standard Java development tools to create or modify the required JavaBeans.
    Listing 1. Sample DTO
    package com.hello.dto;
    
    public class HelloWorldData {
    	private String value;
    
    	public String getValue() {
    		return value;
    	}
    
    	public void setValue(String string) {
    		value = string;
    	}
    }
  2. Identify or create a Java class, either a Plain Old Java Object (POJO) or a Stateless Session EJB, that becomes the Web service implementation. The Java class must include the methods to be exposed in the Web service interface. These methods must use the DTOs from Step 1 as the input and output arguments. Note that the methods implementing the business logic exposed in the Web service must be marked as public. Again, you can use standard Java development tools to create or modify the Java class, as necessary. This class does not have to adhere to the rules for a JavaBean. The class may throw any exceptions in the exposed methods, as necessary.
    Listing 2. Sample POJO implementation
    package com.hello;
    
    import com.hello.dto.*;
    import com.hello.dto.*;
    
    public class HelloWorld {
    
    	public String doIt(HelloWorldData input)
    	{
    		String retVal = null;
    		if (input != null)
    		{
    			retVal = input.getValue();
    			System.out.println("Input value: " + retVal);
    		}
    		return retVal;
    	}
    }
  3. Use a Web services tool to generate the Web service implementation from the Java class. There are several candidate tools of varying levels of sophistication, in that they may produce all or only some of the artifacts required by JAX-RPC to deploy and use the Web service. These tools all generate a WSDL document based on the signature of the Java class from Step 2. The tools create a complex type definition embedded in the WSDL types element for each data type (JavaBean) used in the public methods in the Java class. They also create an operation element in the portType for each public method in the Java class. The tools may also generate any other provider-side artifacts required to deploy the implementation as a Web service in an application server.

    Examples of tools on the low end of the spectrum include the command line based Java2WSDL tools from Apache Axis and IBM's WebSphere Application Server. These tools produce only the major artifacts such as a WSDL file and deployment code. An example of a high-end tool is the GUI-driven Web service wizard in the IBM® Eclipse-based WebSphere® Studio family of enterprise application development tools such as Application Developer. This Web service wizard produces all of the JAX-RPC artifacts and the target application-server specific artifacts. In fact, the wizard can even deploy and start the Web service if desired.


    Listing 3. Generated schema element inside the types element of the generated HelloWorld.wsdl
    <schema elementFormDefault="qualified" targetNamespace="http://dto.hello.com"
    xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:impl="http://hello.com" xmlns:intf="http://hello.com" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    	<complexType name="HelloWorldData">
    	    <sequence>
    	    <element name="value" nillable="true" type="xsd:string" />
                </sequence>
    	</complexType>
    </schema>

    Table 1. List of generated artifacts for Java2WSDL for server-side
    File nameDescription
    Java Resources/com/hello/HelloWorld_SEI.java Service Endpoint Interface
    Java Resources/com/hello/dto/HelloWorldData_Deser.javaDeserialize DTO from XML message
    Java Resources/com/hello/dto/HelloWorldData_HelperjavaHelper class that contains DTO metadata
    Java Resources/com/hello/dto/HelloWorldData_Ser.javaSerialize DTO into XML message
    WebContent/WEB-INF/wsdl/HelloWorld.wsdlWSDL returned from wsdl HTTP request
    WebContent/WEB-INF/webservices.xml JAX-RPC server deployment descriptor
    WebContent/WEB-INF/webservices.xmJAX-RPC server deployment descriptor
    WebContent/WEB-INF/web.xml Web services servlet definition
    WebContent/WEB-INF/ibm-webservices-bnd.xmiWebSphere-specific binding extensions
    WebContent/WEB-INF/ibm-webservices-ext.xmi WebSphere-specific extensions
    WebContent/WEB-INF/HelloWorld_mapping.xmlWSDL to Java mapping metadata
    WebContent/wsdl/com/hello/HelloWorld.wsdlCopy of WSDL required by some runtimes such as process choreography
  4. Use a Web services tool to generate the artifacts for the Web service requester using the WSDL generated in Step 3. The tools generate a Java class (DTO) for every complex type defined in the WSDL types element, a service endpoint interface (SEI) that has a method for each operation included in the portType, and a stub that implements the SEI that a client can use to send requests to and receive responses from a Web service implementation. The tools may generate other artifacts, depending on the nature of the requester (J2EE container or not) and the tool itself. The same tools that generate the provider implementation will typically have a requester version as well. Therefore, the same range of tools exists from the command line driven WSDL2Java from Apache Axis or Application Server to the Web service wizard in the WebSphere Studio Application Developer.

    Table 2. List of generated artifacts for WSDL2Java for client-side
    File nameDescription
    Java Resources/com/hello/HelloWorld.javaService Endpoint Interface for client
    Java Resources/com/hello/HelloWorldProxy.javaClient Proxy implementing interface
    Java Resources/com/hello/HelloWorldService.javaInterface for client-side service locator
    Java Resources/com/hello/HelloWorldServiceLocator.javaImplementation for service locator
    Java Resources/com/hello/HelloWorldSoapBindingStub.javaClient-side Stub implementation
    Java Resources/com/hello/dto/HelloWorldData.javaClient-side DTO implementation
    Java Resources/com/hello/dto/HelloWorldData_Deser.java Deserialize DTO from XML message
    Java Resources/com/hello/dto/HelloWorldData_HelperjavaHelper class that contains DTO metadata
    Java Resources/com/hello/dto/HelloWorldData_Ser.java Serialize DTO into XML message
    WebContent/WEB-INF/wsdl/HelloWorld.wsdl WSDL for client request
    WebContent/WEB-INF/webservicesclient.xml JAX-RPC client deployment descriptor
    WebContent/WEB-INF/ibm-webservicesclient-bnd.xmiWebSphere-specific binding extensions
    WebContent/WEB-INF/ibm-webservicesclient-ext.xmi WebSphere-specific extensions
    WebContent/WEB-INF/HelloWorld_mapping.xmlWSDL to Java mapping metadata

Steps 1 through 3 must be performed by the service provider. Step 4 must be performed by the service requester. The service requester can perform Step 4 only after the service provider provides the WSDL from Step 3. Note that in the situation described, the WSDL is not likely to be a standard or even available publicly. However, Step 4 is exactly the same as if the WSDL came from a public source like a service registry.

Figure 1. Bottom-up development pattern
Figure 1. Bottom-up development pattern

Evaluation of the bottom-up approach

The advantages of the bottom-up approach are:

  • It is a quick way to expose legacy implementations as Web services.
  • It requires little or no knowledge of WSDL or XML because the WSDL document is generated by the tools.
  • It has excellent tools support. In fact the sophisticated tools do all the work to create a deployable, executable Web service implementation on the provider side and all the work to allow a request to access the implementation on the requester side.

The disadvantages of the bottom-up approach are:

  • The generated schema defining the data types in the WSDL document derives only from the Java classes from the provider's environment and not from any standards-based schema (see Listing 3 above).
  • The provider-side data types may not be simple DTOs, in that they include additional business logic. Such logic can't be reconstructed on the requester side.
  • The generated schema is embedded in the WSDL, which makes reuse of the schema, perhaps in the definition of other Web services, more difficult. It is possible, of course, to extract the schema from the original WSDL document.
  • The development of the server-side Web service implementation and the client-side Web service requester can't proceed in parallel. The server-side skeleton and DTOs have to be developed before a WSDL can be generated that can be used to generate the client-side stubs and DTOs.
  • Incremental changes to the interface are more difficult to manage. For example, if the interface of the class that implements the service is changed and the WSDL is regenerated, more significant changes could occur in the WSDL, thus causing interoperability with existing clients to fail. The basic problem is that, on the server-side, the class implementing the service is deemed the master interface and, on the client-side, the WSDL provided by the server-side is the master interface. These two different masters can cause the interfaces to become out of sync and difficult to debug and fix.
  • The namespaces of the embedded schema types are typically generated from the Java package names of the server-side JavaBeans. Therefore, if the package names are changed, the namespace will be changed, which means the types are no longer compatible. Most of the tools allow a package to namespace mapping, but this must be explicitly set during the execution of the tool.

Top-down development

In top-down development, both client-side and server-side developers use WSDL (the top) to produce the artifacts (the bottom) necessary for their respective environments. Top-down development is an increasingly common practice for at least two important reasons. First, in many cases, the WSDL describing a service is available publicly in some registry (like a UDDI). With the tools available today, the server-side developer can start with the WSDL to define new implementations of the portType defined by the WSDL, and the client-side developer can start with the same WSDL to develop a client of the service. Second and even more important is the industry trend towards defining interoperable data standards using XML Schema Definitions (XSD). These industry standard data types defined using XSDs can be ideal for defining new Web services interfaces. Therefore, the top-down development pattern starts by identifying or developing XML schema relevant to the domain of the Web service, and then creating a WSDL for the Web service. Development of both the client and server side can then begin in parallel.

The top-down development pattern encompasses the following development steps as illustrated in Figure 2:

  1. Identify or create an XML schema relevant to the problem domain that describes the input and output data types for Web services operations. The data types should be defined in one or more schema (.xsd) files. You can use standard schema development tools to create or modify the necessary schema.
    Listing 4. Sample HelloWorldData.xsd
    <?xml version="1.0" encoding="UTF-8"?>
    <schema elementFormDefault="qualified" targetNamespace="http://dto.hello.com"
    xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:impl="http://hello.com" 
    xmlns:intf="http://hello.com" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    	<complexType name="HelloWorldData">
    		<sequence>
    			<element name="value" nillable="true" type="xsd:string" />
    		</sequence>
    	</complexType>
    </schema>
  2. Create a new WSDL file that contains a types element that imports (not includes) the schema files from Step 1 and contains a portType that in turn contains operation elements referencing the data types defined in the imported schema as input and output parameters. The recommended style for creating this WSDL is wrapped-document literal to be WS-I compliant and for maximum interoperability with .NET environments. Sophisticated enterprise application development tools like the WebSphere Studio family include WSDL editors that provide tremendous assistance when creating WSDL documents. See Create Wrapped Document-Literal WSDL in WebSphere Studio Application Developer for more information.
    Listing 5. Sample HelloWorld.wsdl schema element that contains an import
    <schema elementFormDefault="qualified" targetNamespace="http://hello.com" 
    xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:impl="http://hello.com" 
    xmlns:intf="http://hello.com" xmlns:tns2="http://dto.hello.com" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        <import namespace="http://dto.hello.com" schemaLocation="WorklistData.xsd"/>
  3. Generate the provider-side and requester-side JAX-RPC artifacts. Note that these steps, described below, can be done in parallel by two different and independent teams. The implementation platform on each side can also be different.
    1. Use a Web services tool to generate the provider-side artifacts. A spectrum of tools exists, ranging from the command line driven WSDL2Java from Apache Axis or WebSphere Application Server to the Web service wizard in the WebSphere Studio family. The tools generate a Java class (a DTO) for every complex type defined in the WSDL types element. They also generate either a POJO or a stateless session EJB skeleton service implementation that has a method for each operation included in the portType. The tools may also generate any other provider-side artifacts required by JAX-RPC to deploy the implementation as a Web service in an application server. Examples of these artifacts include the webservices.xml file. There may also be other application server dependent metadata files generated by the tools. After running the tool, the serer-side developer must implement the appropriate business logic to fulfill the semantics of the operations in the service definition.

      Table 3. List of generated artifacts for WSDL2Java for server-side
      File nameDescription
      Java Resources/com/hello/HelloWorld.java Service Endpoint Interface for server
      Java Resources/com/hello/HelloWorldSoapBindingImpl.javaServer-side Stub implementation
      Java Resources/com/hello/dto/HelloWorldData.javaServer-side DTO implementation
      Java Resources/com/hello/dto/HelloWorldData_Deser.javaDeserialize DTO from XML message
      Java Resources/com/hello/dto/HelloWorldData_HelperjavaHelper class that contains DTO metadata
      Java Resources/com/hello/dto/HelloWorldData_Ser.java Serialize DTO into XML message
      WebContent/WEB-INF/wsdl/HelloWorld.wsdl WSDL for client request
      WebContent/WEB-INF/webservices.xmlJAX-RPC server deployment descriptor
      WebContent/WEB-INF/ibm-webservices-bnd.xmiWebSphere-specific binding extensions
      WebContent/WEB-INF/ibm-webservices-ext.xmi WebSphere-specific extensions
      WebContent/WEB-INF/HelloWorld_mapping.xmlWSDL to Java mapping metadata
    2. Use a Web services tool to generate the DTOs, SEI, and client stub implementation for the service requester from the WSDL. This procedure is exactly the same as Step 4 in the bottom-up pattern described above. As before, the client-side developer must use the stub to invoke the service from the client-side business logic. See Table 2 for sample artifacts generated for the client side.
Figure 2. Top-down development pattern
Figure 2. Top-down development pattern

Evaluation of the top-down approach

The advantages of the top-down approach are:

  • It supports the use of existing standards-based XSD types. See Listings 4 and 5 above for an example.
  • When new schema types are developed for the current service, they can be easily reused for other services by simply importing the newly developed XSD into the other services.
  • It allows for parallel and independent development of client-side and server-side.
  • Incremental changes to the service are best managed by changing the WSDL itself. Since the WSDL is the common interface (or contract) for both the client-side and server-side, these changes can be easily managed so they don't affect interoperability with existing requesters or providers.
  • The tools will use the namespaces defined in the WSDL to determine the package names of the generated JavaBeans (or DTOs). Most of the tools support namespace to package name mappings. The advantage with starting from WSDL is that both the client-side and server-side can use different package name mappings without affecting the access of the service.

The disadvantages of the top-down approach are:

  • It requires knowledge of WSDL and XSD because both must be manually generated or manipulated. Even the sophisticated tools that exist today to generate WSDL and XSD require detailed knowledge of the structure of WSDL and XSD to ensure proper compliance with standards and optimal performance.
  • Tools support for the top-down approach has generally been more limited than the support for bottom-up, but that support is improving. For example, many tools do not properly handle WSDL files that import schemas instead of embedding them; and fully automated support for producing wrapped-document literal WSDL is lacking. The most common problem with importing schemas is that the XSDs must exist in the same directory as the WSDL file and relative path names don't always work.

It's important to note that you can use the bottom-up process to produce the WSDL that drives the top-down process. For example, you can create the WSDL published in a UDDI registry using the bottom-up process. We recommend that when doing this, you use tools to separate the schema in the WSDL types element from the rest of the definition so the schema can be reused. The key point in any top-down approach is that once the WSDL is produced (either manually or generated from code), it becomes the master interface that is used by both the requester and provider from that point on.


Round-trip development

The two primary methods of Web services development are top-down and bottom-up. Some developers have also used a third method, primarily because of shortcomings or defects in tools, and a lack of thorough understanding of Web services tools and technologies. In what is called round-trip development, the developer uses part of the top-down process followed by parts of the bottom-up process. First, Steps 1-3a of the top-down method are used, primarily to produce the so-called DTOs (possibly based on standards-based XSDs). The DTOs are used in the interface of a POJO or EJB, which is created manually, offering public methods corresponding to the portType operations defined in the WSDL document. Then, Steps 2-4 of the bottom-up method are used. Step 3b from top-down is skipped because the WSDL from Step 3 of bottom-up is used for the client-side. The entire process is shown in Figure 3.

Figure 3. Round-trip, WSDL to Java to WSDL development pattern
Figure 3. Round-trip, WSDL to Java to WSDL development pattern

Evaluation of the round-trip approach

The primary advantage of the approach is that it you can use it to circumvent tooling problems, or to compensate for insufficient knowledge of Web services tools and technologies. This approach allows customization of an existing schema and Web service via code changes rather than schema changes. You can also use it if the tooling does not support implementation of the service in the desired form, such as an EJB.

The disadvantages of the round-trip approach are:

  • Some Java base types do not round-trip to schema types very well, which can cause additional rework. See the article Web services programming tips and tricks: Roundtrip issues, an introduction for more information.
  • The additional steps required for round-trip unnecessarily complicate the development process.
  • The WSDL produced is much less reusable than the original WSDL and its imported schema.
  • The namespaces of the data types from the original WSDL and the final output WSDL may become different because of the namespace to package mapping and package to namespace mapping. This must be carefully managed by the server-side developer.

Conclusion

Developers have been implementing Web services for some time now, but few have practiced rigorous development approaches. This article described three development patterns that you can use to develop Web services based on the currently available tools.

The bottom-up pattern is the best approach for exposing existing function as a Web service. The top-down pattern offers the most flexibility and reusability, and is rapidly approaching the status of a best practice when developing new Web services. The round-trip pattern can be used as an aide when one of the better methods cannot be used. However, based on our observations in actual customer engagements, our recommendation is to start with a top-down approach to guarantee the best standards-based and evolving interface. Use a bottom-up approach secondarily if existing function needs to be quickly exposed. Finally, avoid round-trip approaches altogether due to the problems with the inconsistencies and development drawbacks in the approach.

Resources

Learn

Get products and technologies

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, SOA and web services
ArticleID=97819
ArticleTitle=Web services development patterns
publish-date=11022005