Monday, February 9, 2009

Meet The Web, RESTfully

This article introduces web interfaces to the JMS message services.

JMS has become a de facto reliable message service for the enterprise applications. As the train of applications has moved to the web, it is a natural requirement for the messaging service to be reachable from web applications. Or as a matter of fact, from any http capable applications.

A popular web interface is the RESTful style API. This article discusses the message service web interface in the context of the RESTful style API.

The "Representational state transfer (REST) is a style of software architecture for distributed hypermedia systems such as the World Wide Web." (Quoted from wikipedia) If you are new to the REST terminology, here is a link to a nice introduction to what it is.

http://en.wikipedia.org/wiki/Representational_State_Transfer

An usage example for the interface is to have AJAX applications (running in a browser) to send or receive messages to the message service. Another usage example of the interface is to have C# applications talk to Python applications asynchronously.

There are commercial (MOM) products that provide the interface and implementation. At the time of this writing, most of the implementation are in the transition to a more mature states. The following are some of the examples.

Apache Active MQ introduced a (accidental) RESTful API to its messaging service:
http://activemq.apache.org/rest.html

The recent release (MQ4.3) of Sun Java Message Queue introduced a more comprehensive web API and implementation:
https://mq.dev.java.net/4.3-content/ums/umsIntro.html


The following section presents a conceptual model (design and implementation overview) of a RESTful messaging service. This can be used as a reference to implement a simple RESTful message service to interface with your favorite messaging provider. The contents presented here assumed that the reader is familiar with basic HTTP protocol and JavaServlet Technology.

The model can be divided into two separate components. The first component is the interface (URI and protocol) to the service. The second component is the service implementation. Each component is elaborated in more details below.

1. The interface to the message service.

A RESTful MOM interface can be (naturally) modeled around Destinations. A destination is a resource that applications used to send or receive messages.

1.1 URL and protocol to send a message.

A message production service URI used to send messages to a destination can be designed as follows.

http://www.effectivemessaging.com/jms/production/queue/destination_name/

where "queue" in the URI identifies that the destination is a queue domain.
where "destination_name" is the name of the JMS destination in the messaging system.

For example, the following represents a protocol (interface) to send a message to the destination "myQueue" in the queue domain.

http://www.effectivemessaging.com/jms/production/queue/myQueue/

The HTTP method POST MAY be used for the "message production" protocol message.

The body of the HTTP message is the message body to be sent to the destination.

The "Content-Type" can be used to specify the content of the message.

The HTTP response status code is used to indicate the status of the request service.

An example protocol interaction (HTTP request-response message) to send a "HelloWorld" to destination "myQueue" would look like this:

----------------- HTTP Request ------------------
POST /jms/production/queue/myQueue/ HTTP/1.1
Content-Type: text/plain;charset=UTF-8
User-Agent: Java/1.6.0_07
Host: localhost:8888
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 10

HelloWorld

----------------- HTTP Response ---------------
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/plain;charset=UTF-8
Content-Length: 0
Date: Mon, 02 Feb 2009 21:59:58 GMT
-----------------------------------------------------

1.2. URL and protocol to receive a message.

A message consumption service used to receive messages from a destination can be designed as follows.

http://www.effectivemessaging.com/jms/consumption/queue/destination_name/

where "queue" in the URI identifies that the destination is a queue domain.
where "destination_name" is the name of the JMS destination in the messaging system.

For example, the following represents a protocol (interface) to receive a message from the destination "myQueue" in the queue domain.

http://www.effectivemessaging.com/jms/consumption/queue/myQueue/

The HTTP method POST MAY be used for the "receive" protocol message.

The received message body is set in the body of the HTTP response message.

The response message "Content-Type" can be used to specify the content of the response message.

The HTTP response status code is used to indicate the status of the request service.

An example protocol interaction (HTTP request-response message) to receive a message from destination "myQueue" would look like this:

----------------- HTTP Request --------------
POST /jms/consumption/queue/myQueue/ HTTP/1.1
Content-Type: text/plain;charset=UTF-8
User-Agent: Java/1.6.0_07
Host: localhost:8888
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 0

----------------- HTTP Response ---------------
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/plain;charset=UTF-8
Content-Length: 11
Date: Mon, 02 Feb 2009 23:04:05 GMT

HelloWorld
---------------------------------------------------

2. Message Service Implementation.

One simple and straight forward implementation for the above service is to use the Java Servlet techonology. A servlet can be deployed in a container (such as Tomcat) to provide the send and receive services.

When the servlet is invoked, it obtains the service type (send or receive), destination domain (queue or topic), and destination name from the request URI. Theservlet then performs the messaging service on behalf of the request. The servelet may use cached Connections. The JMS Session/Producer/Consumer objects are created (or obtained if cached) to perform the requested services.

An appropriate status code and message body are returned to the client in the HTTP response message.

A special thanks to Keith Babo and Frank Kieviet at Sun Microsystems, Inc. for their input to the content of this article.






1 comment: