This article outlines the Apache Wink 1.0 framework architecture and explains the design, implementation, and deployment of a new sample Apache Wink RESTful service. This article also helps you understand the basics of the REST paradigm, going on to explain the details of the new JAX-RS 1.0 standard, which helps Java developers implement RESTful Web services using annotations.
Let's begin with a quick introduction to REST. Representational State Transfer is the set of architectural principles that the World Wide Web is based on. It was identified by Roy Fielding in his doctoral thesis, "Architectural Styles and the Design of Network-based Software Architectures." In his thesis, Fielding lays down the following five architectural tenets of REST and, by extension, the World Wide Web:
- Addressability. Everything in REST is based on the concept of a resource, which is an abstraction not unlike objects or nouns in OOP and must be addressable or reachable via a URI.
- Interface uniformity. Unlike SOAP or other standards, REST requires
that the methods or verbs used to manipulate resources not be arbitrary.
This means that the developer of the RESTful services is limited to
HTTP-supported methods like
GET,PUT,POST,DELETE, and so on. This avoids the need for WSDL-like service description languages. - Statelessness. For purposes of scalability, the server side does not store the state information of the client. This frees the server from being tied to specific clients, and load-balancing becomes much simpler. This also has the added advantage of making the servers easy to monitor and also more reliable to network failures.
- Representational. Clients always interact with some representation of a resource, never directly with the resource itself. There could also be multiple representations of the same resource. Any client holding a representation of a resource, in theory, should have enough information to manipulate the underlying resource.
- Connectedness. Any REST-based system should anticipate the client need to access related resources and should include them in the representations of the resource returned. For example, related steps in the chain of actions for a particular RESTful service could be included as hyperlinks that allow the client to follow them, if chosen.
Why another Java standard? JAX-RS is the new specification that was defined to simplify REST-based Java development. It focuses on using Java annotations and plain old Java objects (POJOs) for RESTful service implementations. Even though historically it was always possible to implement RESTful services using servlets, there was always too much HTTP getting in the way of implementing the business logic.
JAX-RS hides all that HTTP and binds the servlets nicely to individual methods in the Java classes. Annotations can also dynamically extract information from HTTP requests and map application-generated exceptions to HTTP response codes. These are some of the reasons JAX-RS is an effective way to implement RESTful Java Web services.
I've rumbled with REST, jumped over JAX-RS, and finally arrived at Apache Wink. Apache Wink 1.0 is a fully compliant implementation of the JAX-RS 1.0 specification designed from the ground up. It is easy to use and production ready, and it provides a set of features that enhances the core JAX-RS specification.
The Apache Wink run time architecture is a straightforward implementation of the JAX-RS 1.0 specification. Apache Wink is deployed on a Java Platform, Enterprise Edition (Java EE) environment and at a high level is comprised of the following three components:
- The Apache Wink
RestServlet. TheRestServletis configured in the Java EE web.xml descriptor file of the Web application. This servlet serves as the primary entry point of all the HTTP Web service requests and delegates the request and response object instances to the request processor for further processing. - The request processor. The
RequestProcessoris the core Apache Wink engine that is initialized by the Apache WinkRestServlet. The request processor uses the request URI to find, match, and invoke the corresponding resource class and method. Any exception that occurs during the request processing results in theRequestProcessorinvoking the Error Handler Chain for processing the exception. - The resource. In REST, any component or object that represents the Web service is termed resource. A resource enables the retrieval and manipulation of data through one of its many representations. Any POJO that implements the resource is known as the resource class. Resource classes further implement the resource methods that actually handle the underlying business logic.
This entire request cycle is termed the Apache Wink logic flow, as shown in Figure 1.
Figure 1. Apache Wink logic flow
Apache Wink not only helps with the implementation of RESTful Web services but also provides a powerful client library for the easy consumption of RESTful services. Finally, Apache Wink is packaged with an array of built-in providers that assist developers in supporting these industry-standard data formats: XML, Atom, RSS, JSON, CSV, and HTML.
It's time to get your hands dirty with some coding. To make it interesting, you're going to design, implement, and deploy a non-trivial RESTful service on Apache Wink 1.0. This service is a RESTful wrapper to the PayPal Payflow payment gateway service that enables credit card processing over the Internet. However, you'll limit yourself to its transactional inquiry capability for purposes of this example. This function enables you to look up the status of any transaction given a unique ID that belongs to the authenticated user.
Start by defining an interface model to the service and assigning URIs to it that would officially make it a resource in REST. Because all that your service is going to do is serve transactional status, you might expose the URIs mentioned in Listing 1.
Listing 1. URI patterns for the transaction service
/transactions
/transactions{id}
|
The /transactions URI signifies all the transactions in the system. To look up the status of an individual transaction, the /transactions{id} is used. The {id} represents the unique alphanumeric value that corresponds to the transactional ID of the transaction model. Also, to authenticate a specific user, you use the pattern in Listing 2, where UNAME, VNAME, PNAME, and PWD are part of the Payflow gateway login credentials assigned to a merchant when signing up. However, in order to avoid these credentials being intercepted or cached on the network, it is recommended to use an encrypted HTTPS connection and pass in the credentials as request header parameters.
Listing 2. URI pattern with user credentials in the query string
GET /transactions{id}
username=UNAME
vendor=VNAME
partner=PNAME
password=PWD
|
Generally, the URI structure when published externally can cause coupling by the client developer and can restrict a server's freedom to modify its URI space. However, for the purposes of this article I will ignore that design constraint.
Every RESTful interface has to decide on the different kinds of representations it supports to its clients. XML, JSON, HTML, and Atom are just some of the options that Apache Wink 1.0 can support, but this example goes with JSON, as it's a popular format and the JavaScript code is easy to consume for Ajax applications. Listing 3 is an example of the status of a transaction representation formatted as a JSON string.
Listing 3. Transaction status response as a JSON string
{
"RESULT":19,"PNREF":"V19A2A1A7CC5",
"RESPMSG":"Original transaction ID not found: V19A2A192BE9",
"AUTHCODE":null,"CVV2MATCH":null,"AVSADDR":null,
"AVSZIP":null,"IAVS":null,"CARDSECURE":null
}
|
It is worth noting that the use of JSON as a data format for responses can cause service level coupling on out-of-band knowledge of the actual JSON structure being used.
Finally, you have to decide which HTTP methods you will use to operate on the
resources and their functionality. It is important to stick to the classical usage
of these HTTP methods and not try to deviate from them. For example,
GET should be a safe, read-only idempotent call
and should not alter the state of the resource in any manner. Failure to follow
this guideline results in complexity and added confusion for clients. In this case,
because you want to perform a read-only lookup of the status of a single transaction, the GET method is an obvious fit using the URI
pattern, as shown in Listing 4.
Listing 4. Transaction service sample URI pattern
/transactions{id}
|
Each GET invocation returns a JSON-formatted data
representation of the status of the transaction being queried, as shown in
Listing 5.
Listing 5. GET request with transaction ID
GET /transactions/V19A2A192BE9 HTTP/1.1 |
However, there is an issue with this model of querying the transaction status: The service has no way of authenticating that the user querying the transaction is indeed the owner of the transaction. To overcome this issue, allow clients to pass in their login credentials as request header parameters on the URI to enable authentication, as demonstrated in Listing 6.
Listing 6. GET request with security credentials as request header parameters
GET /transactions/V19A2A192BE9 HTTP/1.1 user=winktest vendor=winktest partner=PayPal pwd=wink123 |
Apache Wink service implementation
An Apache Wink service is implemented as a POJO or plain Java class that uses JAX-RS
annotations to map incoming HTTP requests to Java methods. By default, services
can be singletons or are created on a per-request basis. In this example, you create
a TransactionResource class to implement the Apache
Wink RESTful service. It parses the incoming status lookup request, authenticates
the user credentials, calls the Payflow gateway service, and then returns the status
of the transaction formatted as a JSON object. Listing 7 provides
a code snippet from the TransactionResource class.
Listing 7. Apache Wink service Java class snippet
package org.openengine.wink.example.payflow;
import ...;
@Path("/transactions")
public class TransactionResource {
@GET
@Path("{pnref}")
@Produces(MediaType.APPLICATION_JSON)
public JSONObject doInquiry(@PathParam("pnref") String pnref,
@HeaderParam("user") String userName,
@HeaderParam ("vendor") String vendorName,
@HeaderParam ("partner") String partnerName,
@HeaderParam ("pwd") String password) {
try {
if(userName!=null && vendorName!=null
&& partnerName!=null && password!=null)
return getTxnStatus(pnref, userName,
vendorName, partnerName, password).toString();
else
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
} catch (JSONException e) {
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
....
|
The @javax.ws.rs.Path annotation denotes the class as a JAX-RS service. All JAX-RS services require this annotation. The value of the @Path annotation /transactions signifies the relative path of the URI of the transaction service.
The @GET annotation signifies the HTTP verb that the
method itself maps to. The value of the @Path annotation
at the method level refers the sub-root relative to the main URI. The {pnref} in the method level @Path and the @PathParam signify the value of the unique ID for the transaction. For example, if the incoming URI is /transactions/V19A2A192BE9, the V19A2A192BE9 string will be injected into the {pnref} parameter of the getTxnStatus method.
The @javax.ws.rs.HeaderParam annotation is similar to the
@PathParam, but injects individual request header parameters into Java parameters, as shown in Listing 8.
Listing 8. URI with request header parameters
/transactions/V19A2A192BE9 user=winktest vendor=winktest partner=PayPal pwd=wink123 |
Apache Wink service configuration
Apache Wink applications are typically deployed in a servlet container like Apache Tomcat and packaged as a WAR file. Like any other Web application, Apache Wink services also need a web.xml file. Listing 9 provides the contents of the web.xml file of the sample Apache Wink service.
Listing 9. web.xml Web configuration file
<web-app> <display-name>Wink demo</display-name> <description>Demonstration of SDK features</description> <!-- Wink SDK servlet configuration. This servlet handles HTTP requests of SDK web service on application server.--> <servlet> <servlet-name>restSdkService</servlet-name> <servlet-class> org.apache.wink.server.internal.servlet.RestServlet </servlet-class> <init-param> <param-name>applicationConfigLocation</param-name> <param-value>/WEB-INF/application</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>restSdkService</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app> |
As you can see, the Apache Wink RestServlet is
defined in the web.xml file along with its url-pattern.
There is also an initialization parameter for the RestServlet
that points to a file in the /WEB-INF/application directory. This file contains a
list of all the classes and objects that JAX-RS is supposed to deploy. You do
not need this config file and can decide to implement your application class
that will programmatically list the resources your service is implementing, but
this example uses the application configuration file approach instead, as in
Listing 10.
Listing 10. Application configuration file
org.openengine.wink.example.payflow.TransactionResource |
Running the Apache Wink service
To run the service, you must first build and deploy the application on Tomcat. Perform the following steps:
- Download the PayFlow example project from Download.
- Extract the contents of the PayFlow project into a folder on drive C.
The C:\PayFlow directory should look similar to Figure 2.
Figure 2. PayFlow sample project directory structure
- Set your JAVA_HOME and ANT_HOME variables to your corresponding Java and Apache Ant installation directories.
- Add your JAVA_HOME/bin and ANT_HOME/bin to your system PATH variable.
- Launch an Ant build of the PayFlow project by running Ant from the C:\PayFlow
directory.
This step should build the PayFlow project and create a file called PayFlow.war, as shown in Figure 3.
Figure 3. Ant script build output
- Copy the PayFlow.war file to the webapps deployment directory under your
TOMCAT home, as shown in Figure 4.
Figure 4. Deployment of the PayFlow project on the Tomcat server
- Start the Tomcat Web server by running the startup.bat file under the TOMCAT_HOME\bin folder.
- Start a DOS command prompt.
- From the command prompt, enter
telnet localhost 8080(assuming that your Tomcat Web server is configured to listen at port 8080). - Turn on localecho to see what you are doing.
Type
Ctrl+](hold down the Ctrl key and press the right bracket) and enterset localecho. - Press Enter on a blank line
- Enter the following:
GET /PayFlow/rest/transactions/V19A2A192BE9 HTTP/1.1 user: winktest vendor: winktest partner: PayPal pwd: wink123 Host: localhost
- Press Enter twice.
The telnet output should contain the JSON-formatted transaction status as in Figure 5.
Figure 5. for the JSON response containing the transaction status
This article outlined the basics of the REST architecture and the new JAX-RS Java standard, which aims to simplify RESTful service implementations. It focused specifically on the new Apache Wink 1.0 framework, which is a fully compliant, ground-up, easy-to-use implementation of the JAX-RS 1.0 specification. You walked through Apache Wink's underlying architecture, and you designed and implemented a new sample Apache Wink Web service and learned the steps needed to deploy and run it. For more about REST, JAX-RS, or the Apache Wink 1.0 framework, refer to the Resources section of this article.
| Description | Name | Size | Download method |
|---|---|---|---|
| Apache Wink service implementation | PayFlow.zip | 2.51MB | HTTP |
Information about download methods
Learn
-
Apache
Wink Developer Guide: Read the guide to get a more detailed overview of the
Apache Wink framework and its use.
-
Apache Wink Wiki: Explore the various aspects
of the Apache Wink project.
-
Architectural
Styles and the Design of Network-based Software Architectures: Read about
REST in Roy Fielding's dissertation.
-
RESTful Java with JAX-RS: Read
the book by Bill Burke (O'Reilly Media, 2009).
-
RESTful Web Services: Read
the book by Leonard Richardson and Sam Ruby (O'Reilly Media, 2007).
-
RESTful Web
services: The basics (developerWorks, Nov 2008): Read Alex Rodriguez's article
to get a basic understanding of the concepts of REST.
-
JSR 311: JAX-RS: Read the
Java API for RESTful Web Services specification.
- My
developerWorks: Personalize your developerWorks experience.
-
developerWorks
technical events and webcasts: Stay current with the latest technology.
Get products and technologies
-
Apache Wink: Download
Apache Wink and get the source code and binaries of the latest version of the
framework along with other example projects.
-
Apache Tomcat Web Server
version 6.x: Download Tomcat.
-
Apache Ant: Download Ant.
-
IBM Java JDK: Download IBM's JDK.
-
IBM
trial software for product evaluation: Build your next project with trial software available
for download directly from developerWorks, including application development tools and
middleware products from DB2®, Lotus®, Rational®, Tivoli®,
and WebSphere®.

Vishnu Vettrivel is the Principal Consultant at PunditLabs, which specializes in enterprise consulting and technology, and he has over a decade of experience in architecting, designing, designing, and developing mission-critical enterprise applications. Having worked extensively for Fortune 50 clients, he has helped craft strategic technical plans for many emerging technologies. You can reach him at vishnu@punditlabs.com.



