Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

A guest post by Josh Long, the lead author on Apress’ Spring Recipes, 2nd Edition, O’Reilly’s Spring Roo, and a SpringSource open-source project committer and contributor. You can reach him on his personal blog, the SpringSource Blog and on Twitter (@starbuxman).

Hi! I’ve just released a new video series introducing the Spring framework for Pearson’s Livelessons series. The video series runs the gamut of Spring’s various technologies, and introduces, among other things: container basics, web application development, (big-) data processing, messaging and integration, mobile- and cloud-computing with Spring.

In this first post of three, we concentrate on building production-ready REST services with Spring. Spring MVC’s REST support is a great first step, but we can do better. We’ll look at Dr. Leonard Richardson’s maturity model for grading API compliance with RESTful principles and design-patterns like hypermedia, we’ll add support for hypermedia by using Spring HATEOAS (hypermedia as the engine of application state), and we’ll reduce our total lines-of-code and simplify our architecture by using Spring Data REST.

Today’s applications don’t exist in a vacuum. They are distributed, portable, mobile, integrated, social, and connected. Devices are small enough now that there’s no reason an application can’t go with you. We’ve seen the transformation that the rise of smart phones and tablets has had on our lives. What’s powering this transformation? How are these systems communicating? They’re certainly not using SOAP. Or CORBA. Most of them are using REST.

The Richardson Maturity Model

REST is a constraint on HTTP that was originally proffered by Dr. Roy Fielding in his 2000 doctoral dissertation. It is more a style than a standard. REST is not an all-or-nothing technology choice. Users can, and often do, choose to embrace the parts of REST that most effectively suit their use cases. APIs today are often said to be “RESTful” — or not — according to the depth of their compliance with the principals of REST.

We can use the Richardson Maturity Model by Leonard Richardson to classify REST APIs. I think Martin Fowler does a good job explaining the concepts of the various levels, so we won’t endeavor to duplicate their explanations here. Let’s examine an abbreviated look at this:

  • Level 0 (The Swamp of POX) – In this level, the use of HTTP is almost incidental. HTTP is being used merely as the transport. For example, while SOAP services are often deployed over HTTP, but they don’t have to be. They could, just as readily, be deployed over JMS or SMTP. Such services are said to be the least RESTful. POX refers to plain old XML, as many technologies in this level – including SOAP and XML-RPC – use HTTP as a transport for data encoded in XML, usually in a schema that models remote procedure call semantics.
  • Level 1 (Resources) – In this level, a singular service endpoint expands into multiple, distinct HTTP resources, corresponding to objects in your system, like a customer record, or a user record. Responses from these resources might reference other resources by their URIs in this topology. Here, for example, you might expose resources for each entity in a system, like /users/1, /users/2, etc.
  • Level 2 (Transport Native Properties) – In this level the API leverages transport-specific capabilities like headers, status codes, and verbs to build idiomatic HTTP APIs. This is an acceptable entry point into REST architectures.
  • Level 3 (Hypermedia) – The final level introduces something that you often hear referred to under the ugly acronym of HATEOAS. It involves decoupling the API from the URI topology and exposing navigation options to the client as response payload meta-data. This navigation meta-data is conveyed using a wrapper structure for response payloads that contain a collection of navigation options (link), and the payload intended for conveyance.

It’s interesting that most REST framework technologies will start you off at Level 2. If you’re using just Spring MVC and you want to build RESTful services, this is by default where you start. Let’s look at how to build such an API with Spring MVC. Before we do that, however, we need to understand the domain of the backend service.

Our Customer Relationship Manager

Let’s look at an example that has a simple domain: User entities that contain collections of Customer records. Our service tier has the contract shown here – our CrmService supports user profile and customer record manipulation:

It in turn delegates to a repository type. This is defined here, where the interface to our Spring Data JPA-powered repository is working with the JPA entity User:

The interface extends Spring Data’s PagingAndSortingRepository, which provides generic methods for working with JPA entities. In our case, we’re typing this to User entities, which have a generic key of type Long.

The more interesting thing here are the two methods defined in the interface: findByUsername and findUsersByFirstNameOrLastNameOrUsername. These methods will be implemented dynamically by Spring Data. Roughly, the dynamic JPA implementation of findUsersByFirstNameOrLastNameOrUsername will use the JPA EntityManager to run a JPA query of roughly the form SELECT U FROM User U WHERE U.firstName = ? OR U.lastName = ? OR U.username = ?. Pretty neat, right?

The Web Application

The web application hosting our REST API is a standard Servlet 3-compatible Spring MVC application (see this Spring MVC tip. The application uses the Servlet 3 facility to bootstrap the container programmatically (as opposed to using a web.xml)

The CrmWebApplicationInitializer sets up the standard two-tiered configuration in Spring MVC applications: web-application-global Spring contexts are initialized as parents to DispatcherServlet-local contexts. Template methods make it easy to register Servlet infrastructure pieces like Filter instances, and how to customize the servlet that was registered.

The class CrmWebApplicationInitializer configures our Servlet 3 context and our Spring application contexts.

The class WebMvcConfiguration enables Spring MVC (with the @EnableWebMvc annotation) and plugs in an implementation of Spring’s MultipartResolver interface that delegates to the Servlet 3 javax.servlet.http.Part API. The MultipartResolver implementation is used to specify how Spring supports file uploads.

Here is a very brief WebMvcConfiguration:

The @EnableWebMvc annotation provides quite a punch for such a puny annotation! Spring MVC will do a lot of things automatically at this point:

  • Spring MVC supports object-to-XML marshalling in REST services if a JAXB implementation is on the CLASSPATH.
  • Spring MVC supports validation of request payloads using JSR 303 annotations if an implementation like Hibernate Validator is on the CLASSPATH.
  • Spring MVC supports rendering ATOM or ROME feeds if the Rome library is on the CLASSPATH.
  • Spring MVC exposes every bean registered with the @Controller annotation on it as HTTP endpoints.

Our First Cut at a REST API

We know that we want to support a few different resource URIs to work with our data:

  • /users – The root URI for manipulating User records.
  • /users/{user} – Access and manipulate a specific User. {user} is a path variable expression that will be substituted at runtime for whatever values in a URI match this pattern.
  • /users/{user}/customers – Support traversal and modification of the customers collection.
  • /users/{user}/customers/{customer} – Support manipulation of individual customer records.
  • /users/{user}/photo – Support file upload and download for the profile photo for the given user.

The class shown next, a first cut at a REST endpoint supporting our CRM, implements these endpoints:

This is standard Spring MVC: requests are routed by the DispatcherServlet to methods on controller methods based upon a matching process that draws on the configuration specified in each @RequestMapping annotation.

The various controller methods return a value. Most of them return a domain model type — Customer or User (or collections of either) — and have been annotated with @ResponseBody. When discovered on a method’s return value, @ResponseBody triggers the conversion of the returned value into an HTTP response by delegating to any of the configured HttpMessageConverter instances (supporting XML, JSON, etc.).

UserProfilePhotoController supports reading and writing user profile images. UserProfilePhotoController receives uploaded file data and streams file data and ultimately depends upon the MultipartResolver configured in the next code snippet. Arguably, the file upload endpoint should be exposed over HTTP PUT, not POST, but POST works well enough and is easy to use from HTTP browsers. For practical reasons, you might consider exposing file endpoints as both POST and PUT.

Level Up with Hypermedia

Our API works fine, but there are few things that we can improve. First, our API is fragile in that any changes to the URLs would break clients connecting to the system. Additionally, there’s no way to signal to the client what entities are related to this entity and how. Clients must simply understand the domain and the relationships a priori.

One approach that is well defined in the canonical book REST in Practice is called HATEOAS. HATEOAS is part of REST-creator Roy Fielding’s uniform access principle. Roy clarifies these concepts in a few points in this 2008 blog:

  • “A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace.”
  • “A REST API should never have “typed” resources that are significant to the client… The only types that are significant to a client are the current representation’s media type and standardized relation names…” That is to say: the client need only know how to work with ATOM/RSS, images, XLS, generic data encoded as JSON or XML, HTML, media, etc. No further knowledge about implementation types should be required.
  • The client should know about only one URI, the entry point (bookmark) URI. All other navigation should be discovered while interacting with the API. Navigation information is well conveyed using link entities, like this in XML: <link rel ="users" href="" /> or this in JSON: { "rel" : "users", "href" : "" }.

Spring HATEOAS layers on top of Spring MVC and makes it easy to incorporate support for these concerns in your Spring MVC applications. This brings us to Level 3 of the Richardson Maturity Model.

Supporting Hypermedia with Spring HATEOAS

To enable Spring HATEOAS, add the spring-hateoas dependencies to your CLASSPATH, and then update your WebMvcConfiguration class as shown next. This class installs Spring HATEOAS using the @EnableHypermediaSupport annotation and sets the default applicaton-wide content-type by overriding a callback method in the WebMvcConfigurationSupport class.

Central to Spring HATEOAS is the concept of a org.springframework.hateoas.Resource – which is a wrapper for a response payload and navigation links that apply to that payload.

There are many competing formats for resource representation including Collection+JSON, HAL and Siren, and no real established winner (though the trends seem to be favoring HAL). Spring HATEOAS supports its own representation, as well as HAL. The following code demonstrates a resource (and associated links) using Spring HATEOAS’ default representation format. This is a sample representation as returned from a default Spring HATEOAS endpoint:

This demonstrates a rewritten UserController that embraces Spring HATEOAS’ Resource abstraction. The new implementaton delegates to resource assemblers to build the Resource instances, then returns them wrapped in HttpEntity instances. HttpEntity instances convey a response payload (the Resource) as well as HTTP response specifics like HTTP headers and status codes, which are key to building a idiomatic REST API. Here is the updated UserController that uses a Spring HATEOAS Resource:

The ResourceAssembler implementations adapt our response payloads into Resource instances – they assemble them. The ResourceAssembler that adapts Customer entities to Resource<Customer>> instances:

The ResourceAssembler creates a Resource object with a payload and attaches Link instances. Java doesn’t (yet) support method references, but Spring HATEOAS’s ControllerLinkBuilder can create a dynamic proxy of the target controller method’s containing class. When a method on this proxy is invoked, its @RequestMapping mapping information is extracted and used to generate the URI in the link. In this way, configuration (like URI mappings) is only ever specified once. It’s OK to pass in null for all the arguments of the controller method except for the arguments that contribute to the URI itself, such as @PathVariable-annotated arguments. You should pass in the real value there as it’ll contribute to the link’s URI.

The Link builder fluid DSL captures both the URI (through the method-capturing proxy) and a real value, a string that describes the relevance of the URI for any client working with this resource. A resource should only return Link navigations that are valid for the resource in its current state. It would make no sense, for example, to return a Link to obtain a refund on a resource for an order that hasn’t been paid for yet.

Interfacing with a Hypermedia REST API with the Spring REST Shell

From the documentation, “the goal of the rest-shell is to make it much easier to work with HATEOAS HTTP-based REST services by providing a command shell interface that keeps track of where you are in the HTTP resource hierarchy and allowing you to specify URLs by short, relative paths, or by rel reference.” Releases are available on the project’s GitHub page and via the brew package manager on OSX (brew install rest-shell). The code below reproduces a session spent in the shell interacting with our hypermedia-powered API. Here is a session spent talking to the CRM REST API from the Spring rest-shell:

In the session, I navigate URIs by following the link elements. Commands like get and post support issuing the HTTP verbs of the same name. The rest-shell can also discover relevant navigation links if it understands the representation.

Spring Data REST

The UserProfilePhotoController is doing about as little work as possible to satisfy the requirements of the endpoint it exposes. I’m not certain there’s really much that could be done to make this simpler. Our UserController, on the other hand, deals a lot with the state management of User and Customer records — all that has to do with storing, updating, reading or removing them. When we implement this behavior — as often as not — we simply unwrap the request and forward it on to the injected crmService, which in turn — as often as not — forwards the request on to the injected UserRepository instance. So, why not cut out the middle men?

With Spring Data REST, we can do just that! Spring Data REST makes it dead simple to expose RESTful endpoints that work with Spring Data repository instances.

Add Spring Data’s pre-packaged Java configuration class, RepositoryRestMvcConfiguration to the array of configuration classes returned in the getServletConfigClasses method of CrmWebApplicationInitializer. Here is the updated CrmWebApplicationInitializer:

The RepositoryRestMvcConfiguration class automatically detects Spring Data repositories that are annotated with @RestResource and exports them as REST resources. Add the annotation to the UserRepository interface and CustomerRepository interfaces, as shown here where we export the Spring Data REST endpoints with @RestResource:

With Spring Data REST, all of the functionality in our existing UserController is redundant! Disable the UserController class by commenting out the @Controller annotation on the UserController.

Run the updated application ( hateoas-data) and you’ll see the usual endpoints for /users, /users/{user}, /customers, and /customers/{customer} as we had from before. But wait, there’s more! The only endpoints that Spring Data REST didn’t make redundant are the endpoints concerned with manipulating the profile photo. You’ll notice that you get a lot more out of the box than that when you first launch the browser.

/ returns a sort of useful index page of the possible resources and the collections they manage.

Spring Data REST can produce a schema for each resource, for example, http://localhost:8080/users/schema. This is an excerpted part of the schema generated by Spring Data REST for the users resource:

Spring Data REST automatically exports repository finder methods as HTTP endpoints. These finder endpoints simply expose searches from a repository over HTTP. For example, the repository query method findUsersByFirstNameOrLastNameOrUsername is exposed as http://localhost:8080/users/search/findUsersByFirstNameOrLastNameOrUsername?username=joshlong&lastName=long&firstName=josh. I’m not sure you’d want to expose these finder endpoints to external consumers of your API, but it’s a nice feature anyway.

Spring Data REST respects Spring Data’s concepts of paging and sorting. As an example, http://localhost:8080/users/?sort=firstName&page=1 would return all of the users, sorted by the firstName property.

Customizing Spring Data REST

Spring Data REST has a lot of extension points. For example, it is easy to pre- and post-process entity state while persisting entities with @RepositoryEventHandler-annotated beans. Spring will invoke any annotated callback-methods for the appropriate events in the entity lifecycle. This gives us a chance to affect, or validate, the state of the entity before its persisted. This an implementation that responds to lifecycle events for Customer entities. It responds to events for the Customer entity:

Spring Data REST returns well-formatted Spring HATEOAS-powered JSON representations, complete with useful link elements for the associations on the entity, automatically. That’s pretty darned good if you think about it!

Creating a Link in Spring Data REST

Delete the UserController, as it is now obsolete. This impacts all of the link instances we created earlier, since they depended upon a proxy that matches the UserController interface. Instead, use the EntityLinks link-builder. It supports common conventions for entities. For example: given the entity User, it’s expected that /users maps to the collection of User entities, and that /users/{id} will map to a single instance of an entity (as identified by an ID).

The ResourceAssembler implementations are no longer needed and so they can be deleted. The only thing remaining is our UserProfilePhotoController, which creates link elements. Creating link elements is something common enough that it makes sense to extract it out to a common component, like the UserLinks class shown next. Here, the UserLinks class codifies the creation of commonly used Link types:

Now, revise the UserProfilePhotoController class to use the UserLinks bean, as shown here where the updated UserProfilePhotoController uses the UserLinks bean:


This concludes the first of three posts, and in this piece we have introduced Spring’s rich REST support. In the next post we will cover REST API clients using Spring Security and Spring Security OAuth.

Be sure to look at the Spring resources below that you can find in Safari Books Online.

Not a subscriber? Sign up for a free trial.

Safari Books Online has the content you need

Spring Framework LiveLessons (Video Training) provides a walking tour of all of the Spring projects, including: Spring, Spring MVC, Spring Data, Spring Batch, Spring Integration, Spring Security, Spring Social, and more. Josh introduces how to get started building modern day Spring applications while introducing the concepts behind them. In the lessons, Josh guides viewers through a look at the Spring stack and the features designed to support relational data access, NoSQL and big-data access, batch processing, integration and messaging, REST services, mobile clients, OAuth-secured, connected web applications, service provider APIs, and more!
Spring Recipes
continues upon the bestselling success of the previous edition but focuses on the latest Spring 3 features for building enterprise Java applications. This book provides elementary to advanced code recipes to account for the following, found in the new Spring 3.
Spring in Action, Third Edition is totally revised for Spring 3.0, and covers the latest features, tools, and practices including Spring MVC, REST, Security, Web Flow, and more. Following short code snippets and an ongoing example developed throughout the book, you’ll learn how to build simple and efficient J2EE applications.

About the author

joshlongprofile Josh Long is the Spring developer advocate at SpringSource, by Pivotal. Josh is the lead author on Apress’ Spring Recipes, 2nd Edition, O’Reilly’s Spring Roo, and a SpringSource open-source project committer and contributor. When he’s not hacking on code, he can be found at the local Java User Group or at the local coffee shop. Josh likes solutions that push the boundaries of the technologies that enable them. Continue the discussion on his personal blog, the SpringSource Blog and on Twitter (@starbuxman).

Tags: HATEOAS, Leonard Richardson, livelessons, martin fowler, REST, spring, Spring Framework, Spring Hypermedia, Spring MVC,

One Response to “Building Elegant REST Services with Spring”