Saturday, May 26, 2007

RESTful Web Services: JSR-311 (TS-6411) at JavaOne 2007

These are the notes which I took during the RESTful Web Services Technical Session at JavaOne 2007. Eventually the presentation audio will be available but until then this should provide a good overview of what was said.

Speakers: Paul Sandoz, Marc Hadley, Peter Liu

Definition
"REST" is the architectural style of the WWW. Note that "style" is not "architecture". Coined by Roy Fielding in his PhD thesis.

Tenets
Resources
- These can be considered as the Platonic ideal forms. They are identified by "Uniform Resource Identifiers" ( aka "URIs") and realised by "Representations" which are the equivalent of the shadows in our Platonic Cave metaphor.

Methods - Methods are how we interact with the resources. In the HTTP paradigm these are as you would expect GET, POST, etc. The key is that they are a small set and fixed for all resources. They facilitate the exchange of the representations.

Representations - Representations embody the state of a resouce r at time t. Therefore,you can see that there can be multiple, alternate representations of a given single resource R. It can be conceived of as a finite state machine.

REST vs. RPC
RPC
Few endpoints. Few nouns but many verbs e.g.:
musicdb.getRecordings("my_artist")
REST
Many resources, few fixed methods. Many nouns and few verbs e.g.:
GET /music/artist/my_artist/recordings
Caching
REST allows you to cache because caches can understand the semantics in the protocol. These are not embedded in the message as they are in RPC.

HTTP
HTTP is an application protocol. RESTful web services are "of the web". Don't hide / ignore elements in the network which help you - e.g. caches.

Why a Java REST API?
Lots of companies now offer them (Google, Amazon, eBay, etc.) to expose their services. Where both WS-* and REST APIs are offered, REST are more widely used. It is proposed that this is due to their simplicity (they are easy to consume with common web scripting scripting languages such as PHP) and ability to use web browsers for testing.

The current Java web APIs (e.g. the Servlet API) are too low level though they can be used to implement a REST Web Service. There are many opportunities to simplify development as there must be a better way:
  • High level
  • Declarative
  • Clearly maps to REST concepts
  • Takes care of the boilerplate code
  • Makes it easy to do the right thing
  • Provides a graceful fallback to a lower level API when it's needed
API Elements
Java doesn't really have a concept of a Representation or a Resource. If we try and code a REST servlet without the API we see that we would need to implement content negotiation (what form the Representation should take e.g. xml, text, etc.) and path parsing ( e.g. what Resource(s) have been requested ).

Automate Content Negotiation
Declare what content will be returned:
@ProduceMime("application/xml")
protected void doGet(HttpServletREquest request,
HttpServletResponse response)
URI Templates
Declare what method responds to which requests:
@URITemplate("/artists/{id}") public class Artist extends HttpServlet { ...
This means your container should only call this servlet when requests match this template. To take this one step farther we can combine and apply these annotations to a POJO:
@URITemplate("/artists/{id}")
@ProduceMime("application/xml")
public class Artist { @HttpMethod // Needed as we no longer implement HttpServlet InputStream getXml(@URIParam("id") String artist) { ... } @ProduceMime("application/json") @HttpMethod // Needed as we no longer implement HttpServlet InputStream getJson(@URIParam("id") String artist) { ... } @HttpMethod @UriTemplate("recordings") InputStream getRecordingsXml(@UriParam("id") String artist) { ... }
}
Declaring Resource Class Methods
@HttpMethod - The method name can then be anything with the default HTTP methods being taken from the annotated java method name. E.g:
@HttpMethod public XXX getXXX( ) { ... } @HttpMethod("GET") public XXX find( ) { ... }
Method Return Types HttpResponse - provide specialised subclasses for common types of response such as Redirect, Resource Creation, etc.

Representation - provide control of entity related headers such as media type, language, etc.

T - when a default media type can be determined. This is extensible via the SPI.
@HttpMethod
public Recording getRecording( )
Method Parameters
There may be multiple annotated with @URIParam, @QueryParam, @MatrixParam, @HeaderParam (flexible typing) plus zero or one of type Entity or T. E.g.:
@HttpMethod
public Recording updateRecording(
@URIParam("id") String id, Recording updatedRecording)
Deployment Options
  • Servlet and Java APIs for XML web service (JAX-WS) providers will be required by the JSR
  • The Sun Reference Implementation will also add support for Grizzly and the Java SE 6 lightweight HTTP server
  • Restlet support expected - for fall back if needed
  • SPI for other containers
Issues
  • Annotations vs. Classes and Interfaces?
    • Annotations are good for static information
    • Classes and Information are good for dynamic information
    • When to use? It is nice to replace a lot of logic with a nice annotation
  • Resource Lifecycle?
    • Per request, per session or singleton?
  • Container or API - what should go where?
    • Security
    • Filters / Guards
  • Other language support
    • Annotation support is difficult in JavaScript and Ruby
    • Low level APIs start to lose the benefits
Summary
  • High-level declarative programming model
  • REST concepts reflected in the API
  • Flexible typing, runtime takes care of common conversions
  • SPIs to extend capabilities
  • Pluggable support for types, containers, and resolvers
  • Flexible deployment options

No comments: