This is the fifth of a series of articles about setting up a secure RESTful Web Service using Spring 3.1 and Spring Security 3.1 with Java based configuration. The previous article introduced the concept of Discoverability for the RESTful service, HATEOAS and followed with some practical scenarios driven by tests. This article will focus on the actual implementation of discoverability and satisfying the HATEOAS constraint in the REST Service using Spring 3.1. 

The REST with Spring series:

Decouple Discoverability through events

Discoverability as a separate aspect or concern of the web layer should be decoupled from the controller handling the HTTP request. In order to do so, the Controller will fire off events for all the actions that require additional manipulation of the HTTP response.

@RequestMapping( value = "admin/foo/{id}",method = RequestMethod.GET )
@ResponseBody
public Foo get( @PathVariable( "id" ) Long id, HttpServletRequest request, HttpServletResponse response ){
   Foo resourceById = RestPreconditions.checkNotNull( this.service.getById( id ) );
   
   this.eventPublisher.publishEvent ( new SingleResourceRetrieved( this, request, response ) );
   return resourceById;
}
@RequestMapping( value = "admin/foo",method = RequestMethod.POST )
@ResponseStatus( HttpStatus.CREATED )
public void create( @RequestBody Foo resource, HttpServletRequest request, HttpServletResponse response ){
   RestPreconditions.checkNotNullFromRequest( resource );
   Long idOfCreatedResource = this.service.create( resource );
   
   this.eventPublisher.publishEvent ( new ResourceCreated( this, request, response, idOfCreatedResource ) );
}

These events can then be handled by any number of decoupled listeners, each focusing on it’s own particular case and each moving towards satisfying the overall HATEOAS constraint.

Also, the listeners should be the last objects in the call stack and no direct access to them is necessary; as such they are not public.

Read the rest of the article