After watching Jonathan Dahl’s presentation about API design from the Øredev conference last year, especially the parts about Smart Validations, it is apparent that you can do much more to help your client developers than just returning HTTP status code 500 – Internal Server Error, when a request to your REST API fails.
Spring WEB MVC
The Spring Web MVC framework is a great tool for creating restful web services. It takes care of request mapping, validation, serialization and de-serialization just to name a few. When it comes to error handling, the DefaultHandlerExceptionResolver makes a really good job behind the scenes for translating common exceptions to suitable HTTP status codes and adding response headers when applicable. If there is no resource mapped to the request URI, 404 – Not Found, is set as response code. If a HTTP method is not supported by a particular request URI, 405 – Method Not Allowed, is set as response code and the Allow response header is set to indicate which method(s) that can be used instead, and so on.
Unfortunately, things are not always that easy. What about when the developer receives a 400 – Bad Request? Obviously, there is something wrong with the request, but the response fails to tell the developer why it is not accepted. Take a look at the following controller method:
Even with the implementation available, it is impossible to unambiguously determine the cause of failure. Perhaps the de-serialization of the request body to the
User object failed? Maybe the validation failed? Other possible causes of a 400 – Bad Request include erroneous request parameters, missing request headers, etc.
Inspired by Jonathan’s presentation, the idea is that the server will still respond with appropriate status codes, and the appropriate headers when applicable. Additionally, the response body should contain information that can assist the client developer, and in the format that the client requested (as specified by the Accept request header). For example, if the server expects a
name and a valid
ErrorMessage is a simple helper class used for serialization:
There is plenty of more information that may be added to the response that could be valuable for the REST API users. Some suggestions that come to mind are a default message text that could be presented to the end user, a custom error code for client developers or a link to relevant part of the application specific REST API doc, if it is published online.
Another question is how the error handling can be generalized to prevent the
@ExceptionHandler implementation from being copied between all controllers in the project. Note, the example above includes just one of the potential error causes, it is likely that there are more similar implementations for other exceptions.
The ability to use the @Valid annotation as part of a
@RequestBody controller method argument was introduced in Spring 3.1. For completeness, the JAXB validation of the
User class could be implemented as:
The Spring reference documentation provides configuration details.
You may have noticed the
@XmlRootElement annotation on the
ErrorMessage class. It is a JAXB annotation required to make the XML serialization work. No additional dependency is required, since JAXB 2.0 was added to JDK 6u3.
A JSON message converter for serialization and deserialization is added automatically by Spring by just adding Jackson to the classpath. No additional setting is required, however you can tailor the behavior by adding Jackson annotation to your objects.
- Spring 3.1.2.RELEASE
- jackson-databind 2.0.5