Skip to main content

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

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

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.

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

All information submitted is secure.

  • Close [x]

Interactions with WebSphere Process Server and WebSphere ESB using Representational State Transfer

Greg Flurry (flurry@us.ibm.com), Enterprise Integration Solutions Strategist, IBM
Greg Flurry is is a Senior Technical Staff Member in IBM Software Group's Enterprise Integration Solutions. Greg frequently travels to customers to help them define and implement service oriented solutions. His main focus is on the relatively new WebSphere Version 6 Platform Messaging technologies and the application of those technologies to customer solutions. As a prolific author, he has written about 50 articles in his career. Read more about Greg and the articles he has written on the WebSphere author spotlight page.

Summary:  This article uses an example to show you how to implement interactions with WebSphere Process Server and WebSphere Enterprise Service Bus using Representational State Transfer (REST).

Date:  08 Nov 2006
Level:  Intermediate
Also available in:   Japanese

Activity:  5520 views
Comments:  

Introduction

Representational State Transfer (REST) is broad term that definines an architectural style for interaction between systems. It is not a standard with precise rules or well-defined APIs. Nevertheless, interaction using REST (hereafter called "RESTful interaction") is widespread in the Internet world. For a good description of REST principles see the article Building Web services the REST way .

IBM® WebSphere® Process Server and IBM WebSphere Enterprise Service Bus (ESB) are built on the Service Component Architecture (SCA) and Service Data Object (SDO) standards. SCA and SDO let you connect interacting SCA components and modules independent of implementation technology. In SCA, bindings define the physical interaction mechanism between interacting modules. WebSphere Process Server V6.0.1 and WebSphere ESB, V6.0.1 offer bindings for Web services, JMS, and adapters (called EIS bindings). These two products also offer the default binding (SCA binding). None of these bindings, however, are capable of RESTful interaction.

This article discusses some of the considerations and options for enabling RESTful interactions in these two WebSphere products. The article then shows some sample implementations that follow the interaction principles described in the article referenced above.

RESTful Interactions in the context of WebSphere Process Server and WebSphere ESB

RESTful interactions are based on HTTP as the communication transport, with URLs and XML documents as the syntax for interactions. The article referenced above indicates that the HTTP request uses the "logical" URL, the document sent for information transfer from the requester to the provider, and the document received for information transfer from the provider to the requester. There is a URL for each resource and the URL is simply a "noun." The "verb" for the interaction is defined by an HTTP method -- GET, POST, PUT, or DELETE. The reference implies that the interactions do not require "out-of-band" information such as HTTP headers to define the "in band" (business) behavior of the interaction.

SCA modules have a very different syntax derived from classic object-oriented programming environments. So in an SCA interface, there are operations that correspond to "verbs," and request and return parameters that correspond to "resources."

Interaction with RESTful requesters or providers with business or mediation SCA modules for WebSphere Process Server and WebSphere ESB requires "adapters" in the general sense of the word. As shown in Figure 1 below, an outbound adapter accepts a request from an SCA module, sends the request via RESTful HTTP to a RESTful provider, receives the RESTful HTTP response from the provider, and returns the response to the SCA module. An inbound adapter accepts a RESTful HTTP request, sends the request to an SCA module, receives the response from the SCA module, and returns a RESTful HTTP response to the requester.


Figure 1. Adapters for SCA modules
Figure 1. Adapters for SCA modules

Outbound adapter

Consider first the outbound adapter, where the goal is for an SCA module to interact with an existing RESTful "service" with a defined "interface." That interface must first be mapped to an SCA compatible interface.

The most straightforward design of the adapter consistent with Figure 1 is shown in Figure 2 below. The adapter module is independent of any other SCA modules. The adapter module must provide an export that offers an SCA interface appropriate for use by other SCA modules, and the adapter module must of course send RESTful HTTP requests and receive RESTful HTTP responses. The adapter component in the adapter module implements the HTTP interaction. A key aspect of this design is that the adapter component runs in the same thread as the rest of the components in the module, thus offering good performance. The export in the adapter module may or may not have the same interface as the adapter component, as discussed further below.


Figure 2. Adapter module
Figure 2. Adapter module

A good choice for implementation of the adapter is a Java™ component that resides in either type of SCA module (business or mediation), or in a mediation primitive that resides in a mediation flow component in a mediation module. Figure 3 below shows the options for a business module. The design on the left portrays two situations: first, the adapter component defines an interface that is natural for the RESTful service (in other words, it uses the RESTful service’s XML documents as parameters), and the export offers the same interface. This design is a good choice when other SCA modules can be developed or modified to use the natural interface.

In the second situation, the export defines the interface necessary when other SCA modules cannot change. In this case the adapter component must do transformation of the natural interface. This design is a good choice only if minor transformation is needed. In the design on the right, the adapter component offers the natural interface of the RESTful service, while the export offers a different interface that could be mandated by other SCA modules. An Interface Map component supplies the necessary transformation. This design is a good choice when sophisticated interface transformation is required, as it helps keep the adapter component implementation as generic and reusable as possible. With either of these two designs, the adapter component can be considered a form of binding, and the modules can be considered forms of mediation and logically considered as part of an ESB.


Figure 3. Business module options for adapter
Figure 3. Business module options for adapter

If the business module can be modified, and if if performance is critical or separation of concerns is not critical, another option is possible. Figure 4 below shows an optimized form of adaptation in which the adapter component is contained in the business module. Any needed transformation can take place in the business component or in a separate Interface Map component (not shown), which eliminates the remote procedure call needed with the design in Figure 2.


Figure 4. More business module options
Figure 4. More business module options

Interaction with a RESTful service may require some non-business related information "out of band," such as an identity token. While security is not covered in this article, here are some alternatives for handling out-of-band information. The necessary information could exist as part of the environment, like the J2EE security context, or as part of some out-of-band part of a message such as SOAP header. In this latter case, the business module implementations for the adapter module in Figure 2 cannot work, and therefore you must use a mediation module, which can access out-of-band information in a message. One goal of the mediation flow component is to extract the out-of-band information and make it available to the adapter so that, for example, an identity token passed in a SOAP request header could be passed as an HTTP cookie.

Figure 5 below shows two possible designs. On the left, the mediation flow component has access to the entire message, and can examine the header information. However, in WebSphere Process Server V6.0.1 and WebSphere ESB, V6.0.1, the adapter component cannot access the entire message. There are two ways to work around this restriction. First, you could enhance the interface offered by the adapter component beyond what is needed for the business logic to include the out-of-band information. For example, you could add a simple array of <name, value> pairs to the parameters for an operation, and the mediation flow component could extract the information from headers and insert it into the array. Second, the mediation flow component could place the out-of-band information in a Java ThreadLocal instance. Since the adapter component runs in the same thread, it has access to the out-of-band information. In both approaches, the adapter component processes the out-of-band information and inserts it into the HTTP request in the proper form. A similar approach would be needed for the HTTP response: the adapter component would place any returned out-of-band information, like set-cookie headers, in the extended return parameter from the adapter component, or in a ThreadLocal instance. The mediation flow component could then access the information and insert it into, for example, a SOAP response header.


Figure 5. Mediation module options
Figure 5. Mediation module options

An alternative is shown on the right in Figure 5. In this case, the adapter is now a custom mediation primitive inside the mediation flow component. A mediation primitive has full access to request or response header information, and it can access the incoming request header information directly for insertion into the HTTP request. Likewise, a mediation primitive can access the HTTP response headers and insert information directly into the outgoing response headers.

Inbound adapter

The goal of the inbound adapter is to allow a RESTful service to interact with an existing SCA module. The most straightforward implementation of the adapter consistent with Figure 1 is shown in Figure 6 below. The adapter module receives HTTP requests and returns HTTP responses. It must have an import that supports interaction with other SCA modules. Instead of an active component in the outbound adapter, inbound adaptation is implemented with a J2EE servlet coupled to the adapter module via an SCA standalone reference. This design lets the servlet make local calls on the SCA module, and maximizes performance by eliminating any remote procedure calls. The servlet implements the HTTP interaction, but invokes the SCA interface defined by the standalone reference. The import of the adapter module may or may not have the same interface as the standalone reference, as discussed below.


Figure 6. Inbound adapter
Figure 6. Inbound adapter

You can implement the servlet/standalone reference combination in either a business or mediation SCA module. Figure 7 below shows the options for a business module. On the left, the import defines the natural interface for the SCA environment. The servlet uses the interface offered by the import and and maps to a RESTful interface. As with the outbound case, the servlet can do more transformation than just a simple mapping, but this option may reduce reusability. On the right, the servlet uses the natural interface of the RESTful service (maybe because it already exists), while the import offers a different interface that is natural to the SCA system. An Interface Map component supplies the necessary transformation. With either of these two designs, the adapter component can be considered a form of binding, and the modules can be considered forms of mediation and logically considered part of an ESB.


Figure 7. Business module options for adapter
Figure 7. Business module options for adapter

If the business module can be modified, and if performance is critical or separation of concerns is not critical another option is possible. Figure 8 below shows an optimized form of adaptation in which the servlet/standalone reference is contained in the business module. Any needed transformation can take place in the servlet or in a separate Business Interface Map component (not shown).


Figure 8. More business module options
Figure 8. More business module options

As with the outbound situation, there could be out-of-band information used in an interaction. For example, some sort of identity could be required by the SCA module, either as part of the J2EE environment or out of band in a message header. In the former, the servlet might be able to extract the necessary information from the request and insert it into the environment; in this case, the interface used by the servlet can be the same as that of the import, so business module implementations for the adapter module in Figure 6 work. In the case of out-of-band information in a message header, the business module implementations for the adapter module in Figure 6 cannot work, and you must use a mediation module. One goal of the servlet in this situation would be to extract the out-of-band information and make it available to the mediation flow component so, for example, an identity token passed as an HTTP cookie could be placed in a SOAP header.

Figure 9 below shows the mediation module implementation. Either the enhanced interface or ThreadLocal technique mentioned above work for the inbound adapter. With the enhanced interface, the standalone reference has the expanded interface and the import has the natural business interface. With the ThreadLocal technique, the servlet inserts out-of-band information into or retrieves it from a ThreadLocal. Mediation primitives in the mediation flow component manipulate outbound request headers based on information from the servlet, and they examine inbound response headers to provide information to the servlet.


Figure 9. Mediation module option
Figure 9. Mediation module option

Implementation examples

This section describes an implementation of the outbound and inbound adapters described above. The examples assume familiarity with WebSphere Process Server and WebSphere Integration Developer.

Inbound adapter

Suppose that you want to interact with an existing service from the RESTful world, such as a shopping cart service. The RESTful service interface is defined in Figure 10 below. Of course, you must know the data types of the URLs and status codes, as well as the XML schema for the cart and item content; those details will be covered below.


Figure 10. RESTful interface
SemanticURL [HTTP method]Request documentResponse document

Create cart

../cart [PUT]

n/a

Cart URL

Delete cart

../cart/cartID [DELETE]

n/a

Status code

Retrieve cart

../cart/cartID [GET]

n/a

Cart content

Add item

../cart/cartID [PUT]

Item content

Item URL

Delete item

../cart/cartID/itemID [DELETE]

n/a

Status code

The first step is a straightforward mapping to a SCA-compatible interface:


Figure 11. An SCA compatible interface
SemanticOperation Input parametersOutput parameter

Create cart

create()

n/a

Cart URL

Delete cart

delete()

Cart ID

Status code

Retrieve cart

retrieve()

Cart ID

Cart content

Add item

addItem()

Cart ID, Item content

Item URL

Delete item

deleteItem()

Cart ID, item ID

Status code

The next step is to understand the details of the data types and create a library project that holds the data types and the interface. Figure 12 below shows the complex data types. The URLs and status codes are strings. Figure 13 below shows the description of the MyShoppingCart interface.


Figure 12. Data types
Figure 12. Data types

Figure 13. MyShoppingCart SCA compatible interface
Figure 13. MyShoppingCart SCA compatible interface

For the adapter shown on the left in Figure 3, the next step is to create a business module that acts as an adapter module.It must contain an export and a Java component that is the adapter component, as shown in Figure 14 below, which also shows a business module that uses the adapter module. In this case the binding used for import and export does not matter; the example uses the default (SCA) binding.


Figure 14. Business module and adapter module
Figure 14. Business module and adapter module

To construct the adapter module, you must

  1. Create a business module. Make the library available to the module via the Dependency Editor.
  2. Add the Java component and export to the module. Name them as appropriate.
  3. Set the interface for the Java component to MyShoppingCart.
  4. Wire the export to the adapter (Java) component.
  5. Generate the implementation of the adapter component.
  6. Save and deploy the adapter module to the test environment.

Figure 15 below shows the implementation of the adapter component. During initialization, a BOXMLSerializer service is created to (de)serialize the request and response as discussed below. The general form of any of the business logic methods is:

  1. Create the needed URL.
  2. Process the input and invoke the RESTful service.
  3. Process and return the response. Utility methods are used to invoke the service and return the response.

Figure 15. Outbound adapter component code
package sca.component..impl;
			
public class AdapterComponentImpl {
			
	private String outboundURL = "http://../cart";
	private BOXMLSerializer xmlSerializerService = null;
			
	public AdapterComponentImpl() {
		super();
		xmlSerializerService = (BOXMLSerializer) new   
			ServiceManager().
			locateService("com/ibm/websphere/bo/BOXMLSerializer");
	}
			
	public String create() {
		// create URL
		StringBuffer urlString = new StringBuffer(outboundURL);
		// invoke RESTful serviceInputStream is = interactHTTP(urlString, "PUT", null);
		return getCode(is, true);
	}	
			
	public String addItem(String cartID, DataObject lineItem) {
		// create URL
		StringBuffer urlString = new StringBuffer(outboundURL);
		urlString.append("/" + cartID);
			
		// send line item
		ByteArrayOutputStream lineItemOut = 
			new ByteArrayOutputStream();	
		try {
			xmlSerializerService.writeDataObject(lineItem,
				"http://mystore.com", 
			    "LineItem", lineItemOut);
		} catch (IOException e) {
			e.printStackTrace();
		}
		// invoke RESTful service
		InputStream is = interactHTTP(urlString, 
			"PUT", lineItemOut);
		return getCode(is, true);
	}
			
	public String deleteItem(String cartID, String lineItemID) {
		// create URL
		StringBuffer urlString = new StringBuffer(outboundURL);
		urlString.append("/" + cartID+"/"+lineItemID);
		// invoke RESTful serviceInputStream is = interactHTTP(urlString, "DELETE", null);
		return getCode(is, false);
	}
			
	public DataObject retrieve(String cartID) {
		// create URL
		StringBuffer urlString = new StringBuffer(outboundURL);
		urlString.append("/" + cartID);
			
		DataObject parm = null;
		// invoke RESTful service
		InputStream is = interactHTTP(urlString, "GET", null);
			
		try {
			BOXMLDocument doc =
				xmlSerializerService.readXMLDocument(is);
			parm = doc.getDataObject();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return parm;
	}
			
	public String delete(String cartID) {
		// create URL
		StringBuffer urlString = new StringBuffer(outboundURL);
		urlString.append("/" + cartID);
		// invoke RESTful service
		InputStream is = interactHTTP(urlString,"DELETE", null);
		return getCode(is);
	}
			
	private InputStream interactHTTP(StringBuffer urlString,
		String method, ByteArrayOutputStream out) {			
		
		InputStream response = null;
			
		try {
			URL url = new URL(urlString.toString());
			URLConnection conn = url.openConnection();
			HttpURLConnection hConn = (HttpURLConnection) conn;
			hConn.setRequestMethod(method);
			
			if (out != null) {
				// send output
				conn.setDoOutput(true);
				OutputStream os = hConn.getOutputStream();
				os.write(out.toByteArray());
				os.close();
			}
			
			// get response
			response = conn.getInputStream();
			
		} catch (IOException ex) {
			ex.printStackTrace();
			return null;
		}
		return response;
	}
			
	private String getCode(InputStream is) {
		String code = null;
		BufferedReader br =
			new BufferedReader(new InputStreamReader(is));
			
		try {
			code = br.readLine();
			br.close();
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (code.lastIndexOf('/') > 0)
			code = code.substring(code.lastIndexOf('/')+1);
			
		return code;
	}
}

The implementation is relatively straightforward. For the create() operation, there is no input and the response returned from is a simple string . For the delete() operation, the input is the ID of the shopping cart to be deleted, and the response returned is a simple string. For the retrieve() operation, the input is the ID of the shopping cart to be retrieved; the response is an XML document the BOXMLSerializer is used to create a DataObject that can be returned to the SCA component. For the addItem() operation, the input is the ID of the shopping cart to which the item is added as well as the DataObject containing the item information; the BOXMLSerializer is used to help serialize the incoming DataObject into a byte array that can be sent in the HTTP request; once again, the response returned is a simple string. For the deleteItem() operation, the input is the ID of the shopping cart to be deleted and the ID of the item to be deleted, and the response returned is a simple string.

Testing he adapter module can be done using the module debug feature of WebSphere Integration Developer; in this case, it is possible to test the business module, which drives the adapter module. The adapter module and adapter component interacts with a RESTful service implemented as a normal HTTP servlet in its own application; it provides meaningful results to requests. Figures 16 and 17 show the request and response for the retrieve() and addItem() operations; the information in the figures was captured using the TCP/IP monitor in WebSphere Integration Developer.


Figure 16. retrieve() request and response
Request ---
			
GET /cart/IX4456 HTTP/1.1
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, 
text/*
User-Agent: Java/1.4.2
Host: localhost:9082
Connection: keep-alive
			
Response ---
			
HTTP/1.1 200 OK
Content-Language: en-US
Transfer-Encoding: chunked
Date: Sun, 01 Oct 2006 20:39:54 GMT
Server: WebSphere Application Server/6.0
			
<?xml version="1.0" encoding="UTF-8"?>
<mystore:ShoppingCart xmlns:mystore="http://mystore.com" 
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
		xsi:type="mystore:ShoppingCart">
	<cartID>IX4456</cartID>
	<lineItems>
		<lineItemID>lix45</lineItemID>
		<itemID>Pyu879</itemID>
		<price>9.3</price>
	</lineItems>
	<lineItems>
		<lineItemID>liy146</lineItemID>
		<itemID>R78uyt</itemID>
		<price>4.5</price>
	</lineItems>
</mystore:ShoppingCart>


Figure 17. addItem() request and response
Request ---
			
PUT /cart/IX4456 HTTP/1.1
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, 
text/*
User-Agent: Java/1.4.2
Host: localhost:9082
Connection: keep-alive
Content-Length: 275
			
<?xml version="1.0" encoding="UTF-8"?>
<mystore:LineItem xmlns:mystore="http://mystore.com" 
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
		xsi:type="mystore:LineItem">
	<lineItemID></lineItemID>
	<itemID>TY456</itemID>
  <price>13.23</price>
</mystore:LineItem>
			
Response ---
			
HTTP/1.1 200 OK
Content-Language: en-US
Transfer-Encoding: chunked
Date: Sun, 01 Oct 2006 20:47:23 GMT
Server: WebSphere Application Server/6.0
			
http://.../cart/li89uy


Inbound adapter

Assume we wish to expose an existing SCA service to the RESTful world. For the sake of simplicity and symmetry, assume the SCA interface is the same as shown in Figures 12 and 13; further assume the existence of a library containing the interface and types. Finally assume we have freedom to decide how the RESTful interface is defined; this allows us to reuse the definition shown in Figure 10, the more or less "natural" mapping of the SCA interface.

For the form of adapter shown on the left of Figure 7, the next step is to create business module that acts as an adapter module. The adapter module must contain a standalone reference and an import as shown in Figure 18. Further we must create a servlet that invokes the standalone reference. The figure also shows a business module that gets invoked by the adapter module. In this case the binding used for the import and export does not matter; the example uses the default (SCA) binding.

To construct the SCA part of adapter module, you must

  1. Create a business module. Add the library via the Dependency Editor.
  2. Add the Standalone Reference and the import to the module. Name the import as appropriate (the Standalone Reference cannot be renamed).
  3. Set the interface for the import to MyShoppingCart.
  4. Wire the Standalone Reference to the import. In the dialog box asking if you wish to convert WSDL interfaces to Java interfaces, click Yes.
  5. Save the module. The module should not yet be deployed.

Figure 18. Inbound adapter
Figure 18. Inbound adapter

To add the necessary servlet to the adapter module, you must create a dynamic web project, create a servlet in that project, and then add the resulting web archive file to the enterprise archive file that represents the adapter module. Briefly, again assuming familiarity with the tooling, you must

  1. Create the dynamic web project. In the resulting dialog, click the Show Advanced button to add the web archive to a new enterprise archive. Note: You can put the resulting WAR file into the EAR that corresponds to the adapter module. It is a good idea to add the WAR to its own EAR to avoid the possibility that the tooling will delete the web project during project "cleaning."
  2. Add the new dynamic web project to the adapter module EAR. To do so, open the deployment descriptor for the EAR and go to the Module tab and add the WAR.
  3. Add the library to the Java Build Path for the dynamic web project. To do so, use the project properties editor.
  4. Add a new servlet to the project. The easiest way to do that is to right click on the deployment descriptor and select New -> Servlet. You can add new mappings during the creation of the servlet, or add them later by manipulating the deployment descriptor for the dynamic web project. For the purposes of this example, you need a mapping for "../cart" and for "../cart/*". Save the deployment descriptor.
  5. Add the WAR to the adapter enterprise application by editing the enterprise application deployment descriptor. Save the deployment descriptor.
  6. Now deploy the adapter module to the test environment.

Figure 19 below shows the fleshed out implementation of the servlet. The init() method creates a BOFactory for creating business objects, a BOXMLSerializer for (de)serializing DataOjbects, and a service interface for accessing the MyShoppingCart Standalone Reference. Utility methods simplify getting the necessary IDs from the URL and sending the HTTP output. Note that there are some strings that tailor the behavior of the servlet; these could servlet initialization parameters to make the servlet more reusable.


Figure 19. Servlet implementation
package com.test;
			
public class XMLHTTPIn extends HttpServlet implements Servlet {
			
	private BOFactory factoryService = null;
	private BOXMLSerializer xmlSerializerService = null;
	private MyShoppingCart cart = null;
			
	private String namespace = "http://mystore.com";
	private String root_pathInfo = "xxx/cart";
	private String serviceName = "ShoppingCart";
			
	protected void doGet(HttpServletRequest request,
		HttpServletResponse response)
		throws ServletException, IOException {
		// get cart id
		String[] ids = getIDs(request);
		// retrieve the shopping cart
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		
		try {
			DataObject reply = cart.retrieve(ids[0]);
			xmlSerializerService.writeDataObject(reply,
				namespace, serviceName, baos);
		} catch (ServiceBusinessException e) {
			e.printStackTrace(System.out);
		}
		sendOutput(response, baos.toByteArray());
	}
			
	protected void doPut(HttpServletRequest request,
		HttpServletResponse response)
		throws ServletException, IOException {
			
		// get cart id
		String[] ids = getIDs(request);
			
		String reply = null;
		if (ids == null) { // create request
		
			try {
				reply = cart.create();
			} catch (ServiceBusinessException e) {
				e.printStackTrace(System.out);
			}
			
		} else { // add item request
			// get input (line item)		
			ServletInputStream sis = request.getInputStream();
			BOXMLDocument doc =
				xmlSerializerService.readXMLDocument(sis);
			DataObject parm = doc.getDataObject();
			
			try {
				reply = cart.addItem(ids[0], parm);
			} catch (ServiceBusinessException e) {
				e.printStackTrace(System.out);
			}	
		}
		// add information to reply to produce URL
		reply = namespace+"/"+root_pathInfo+"/"+reply;
		sendOutput(response, reply.getBytes());
	}
			
	protected void doDelete(HttpServletRequest request,
		HttpServletResponse response)
		throws ServletException, IOException {
			
			// get cart id
			String[] ids = getIDs(request);
			
			String reply = null;
			if (ids[1] == null) { // delete cart
				try {
				reply = cart.delete(ids[0]);
			} catch (ServiceBusinessException e) {
				e.printStackTrace(System.out);
			}	
			
			} else { // delete item
				try {
					reply = cart.deleteItem(ids[0], ids[1]);
				} catch (ServiceBusinessException e) {
				e.printStackTrace(System.out);
			}
		}
		sendOutput(response, reply.getBytes());
	}
			
	public void init(ServletConfig arg0)
			throws ServletException {
		super.init();
		factoryService =
			(BOFactory) new ServiceManager().
			locateService("com/ibm/websphere/bo/BOFactory");
		xmlSerializerService = (BOXMLSerializer)
			new ServiceManager().locateService
				("com/ibm/websphere/bo/BOXMLSerializer");
			
		try {
			cart = (MyShoppingCart) ServiceManager.INSTANCE.
				locateService("MyShoppingCartPartner");
		} catch (Exception ex){
			System.out.println(ex.getMessage());
		}
	}
			
	private String[] getIDs (HttpServletRequest request) {
		System.out.println("in getIDs");
		// get  ids
		String pi = request.getPathInfo();
		if (pi == null) { // no ids at all
			return null;
		} else { // at least a cart id
			String[] ids = new String[2];
			// get cart id
			int last = pi.lastIndexOf('/');
			if (last == 0) { // cart id only
				String cartID = pi.substring(1);
				ids[0] = cartID;
				ids[1] = null;
			} else { // item id also
				String cartID = pi.substring(1, last);
				ids[0] = cartID;
				String lineItemID = pi.substring(last + 1);
				ids[1] = lineItemID;
			}
			return ids;
		}
	}
			
	private void sendOutput(HttpServletResponse response,
			byte[] output) throws IOException {
		response.getOutputStream().write(output);
		response.getOutputStream().close();
	}
}

The doGet() method always invokes the retrieve() operation; the BOXMLSerializer helps turn the returned DataObject into a byte array to send back in the response. The doPut() method may invoke the create() method or the addItem() method; the distinction is made based on the content of the URL; for the former the servlet simply invokes the create() operation; for the latter, the servlet uses the BOXMLSerializer to create the DataObject used to invoke the addItem() operation; note that the plain ID returned for both operations must be translated to a URL. The doDelete() method may invoke the delete() method or the deleteItem() method; the distinction is made based on the content of the URL; for the former the servlet simply invokes the cart() operation; for the latter, the servlet simply invokes the addItem() operation; a simple string is returned for both operations.

To test the adapter component, you can use a simple Java application that generates the RESTful requests. You can implement a business component in the business module if you want meaningful results from testing. Examine Figures 16 and 17 again. Now the request in those figures comes from a RESTful service requester, and the response comes from the SCA provider.


Conclusion

This article discussed some of the considerations in interaction with RESTful services with SCA modules from the WebSphere Process Server and WebSphere Enterprise Service Bus products. Further the article shows a concrete example implementing both outbound and inbound "RESTful adapters." The considerations discussed and the examples can also be used to deal with more generic HTTP based interactions that might not adhere to all RESTful principles mentioned described in the resources.

Acknowledgements

Some of the key implementation decisions in this article resulted from conversations with Rob Phippen, lead developer for WebSphere Enterprise Service Bus.


Resources

About the author

Greg Flurry is is a Senior Technical Staff Member in IBM Software Group's Enterprise Integration Solutions. Greg frequently travels to customers to help them define and implement service oriented solutions. His main focus is on the relatively new WebSphere Version 6 Platform Messaging technologies and the application of those technologies to customer solutions. As a prolific author, he has written about 50 articles in his career. Read more about Greg and the articles he has written on the WebSphere author spotlight page.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


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. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

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.

(Must be between 3 – 31 characters.)

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

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=173594
ArticleTitle=Interactions with WebSphere Process Server and WebSphere ESB using Representational State Transfer
publish-date=11082006
author1-email=flurry@us.ibm.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Try IBM PureSystems. No charge.

Special offers