Building RESTful Web Services with Jersey
Matthew Turland
Senior Engineer - Synacor, Inc.
Who I Work For
- Internet solutions for ISPs, media companies, and advertisers
- Offices in Buffalo and New York City
- Clientele includes most of the top 20 USA cable providers
- Great company to work for - join us!
http://www.synacor.com
The Topic of the Hour
Jersey!
(Yes, the project's logo could use some work.)
http://jersey.java.net
Jersey is a reference implementation of JAX-RS
(JSR311, Java API for RESTful Web Services)
What We'll Cover
- Setting up a new Jersey project with Maven
- Basics of building a REST service on the Jersey framework
- Testing the REST service using the JUnit and Jersey testing frameworks
Maven in a Nutshell
- Command line tool
- Manages dependencies like a package management system
- Performs builds, either stand-alone or via Ant integration
- Runs JUnit or Selenium tests and generates reports
- Integrates with continuous integration systems like Hudson
http://maven.apache.org
A Note About Versions
- Current version: 3.0.2
- Old stable version: 2.2.1 (what I'm using for this presentation)
- Most Linux package repositories contain one or both
- Common package names:
maven
, maven2
Generating a Starting Project
From a terminal, issue this command:
Parameterized Paths
- Any path segment between curly braces is considered a variable
- A variable name can optionally be followed by a colon and a regular expression (as supported by Pattern) to validate that path segment
- Variable values are exposed to resource methods by using the
@PathParam
annotation in its parameter list
Individual Query String Parameters
Path and Query String Parameters as Collections
Individual Form Parameters
Form Parameters as a Collection
Individual Request Headers
Request Headers as a Collection
Cookies
"... communication must be stateless in nature ... such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server."
Fielding, Roy Thomas (2000). Architectural Styles and the Design of Network-based Software Architectures, Section 5.1.3. (Ph.D. thesis). University of California, Irvine.
Translation: Do not use cookies in a REST web service. Ever.
More Complex Responses
- Response provides methods such as ok() and created() to create a ResponseBuilder instance initialized with a specific response status
- Most methods of ResponseBuilder implement a fluent interface so calls to them can be chained
- Finally, ResponseBuilder provides a build() method to return a configured Response instance
Implementing a Resource List
Checking Responses
- From Wikipedia: "cURL is a computer software project providing a library and command-line tool for transferring data using various protocols."
- HTTP is supported, making the curl CLI tool great for testing resources as you develop them
- Usage:
curl [options] "[url including query string]"
-v
: output request/response headers + response body
--trace
and --trace-ascii
: output all request/response data
-X [method]
: change request method to [method]
(defaults to GET
)
-d [variable=value]
: add variable
to request body with value of value
, may be used more than once
- For more options, check the man page
Retrieving a Resource List
Implementing Resource Creation
Implementing Resource Retrieval
Implementing Resource Metadata Retrieval
Retrieving Resource Metadata
Implementing Resource Updating
Implementing Resource Deletion
Supporting Multiple Representations
- Clients can request a specific representation of a resource using content negotiation via the
Accept
header
- Jersey looks for the most specific resource method that matches the request and sets the
Content-Type
header appropriately if it finds one or returns a proper error response otherwise
Examples of responses:
501 Not Implemented
- unrecognized HTTP method
404 Not Found
- no matching @Path
405 Method Not Allowed
- matching @Path
, but no matching HTTP method annotation
406 Not Acceptable
- matching @Path
and HTTP method annotation, no matching @Produces
300 Multiple Choices
- matching @Path
and HTTP method annotation, multiple matching @Produces
Setting Default Representations
Tip: To support the same types for all resources in an API ...
- implement an abstract base resource class
- specify a
@Produces
annotation at its class level
- make all other resource classes extend that base class
Implementing XML Representations
- Resource methods can accept parameters (request bodies) and return (response bodies) of these types:
- Custom types can be defined using JAXB and used the same way as above
XML with JAXB - Data Structure
XML with JAXB - Implementation
This approach requires more code, but allows the data structure to be kept
separate from code that allows it to be converted to and from XML.
XML with POJOs using JAXB
The User class in this example is the same, but does not use the
@XmlRootElement annotation.
JSON with JAXB - Data
This data structure class is identical to the one in the previous XML
example aside from the specification of a root element name in the
@XmlRootElement annotation. While it can be specified, it's not needed.
JSON with JAXB - Usage
This approach requires more code, but allows the data structure to be kept
separate from code that allows it to be converted to and from XML.
Caching
- Server returns either a
Last-Modified
or ETag
header in its response when a client requests a resource
- Client sends that header value in a
If-Modified-Since
or If-None-Match
header of a subsequent request for the same resource
- If the resource has not changed, a
304 Not Modified
response is returned with no body
- If the response has changed, a
200 OK
response is returned with the new header value and body for the updated resource
Implementing Caching with Dates
Caching with Dates - Miss
Implementing Caching with ETags
Caching with ETags - Miss
Authentication
- For servlet implementations, most stacks roll their own method of handling this
- Jersey server provides no native mechanism
- For Basic HTTP authentication, credentials can be parsed from the request manually
Simulating DELETE Requests
If including a body in a DELETE request, this error will be displayed:
com.sun.jersey.api.client.ClientHandlerException: java.net.ProtocolException: HTTP method DELETE doesn't support output
See http://jersey.java.net/nonav/apidocs/latest/contribs/jersey-apache-client/com/sun/jersey/client/apache/ApacheHttpClient.html
Client client = ApacheHttpClient.create();
Running Tests
API Metadata
- "Web Application Description Language or WADL is an XML format that provides a machine-readable description of HTTP-based web applications... typically REST web services."
- WADL is a W3C Member Submission, but the W3C currently has no plans to take up work on it
- Primary alternative to WADL is WSDL 2.0, where WSDL 1.x was commonly used with RPC services (SOAP in particular) and 2.0 adds support for REST services
- Accessing
http://host:port/application.wadl
will return an XML document describing available URLs, methods, media types, and parameters