Wednesday, 12 June 2013

Third example: RequestEntityMethodArgumentResolver

 For CRUD operations, a PUT request to a URL is common and usually overwrites the entire object. In our case however, this is not possible: some object properties are read-only, and others can only be written if the object has a certain status. So what we need is a _partial_ update.
And although it is usually possible to omit fields from the request body, this does not do what we want. What happens is for missing fields, use the default value from the constructor. But what we want is: for missing fields, to not change the value in the database.
We’ve created an annotation @RequestEntity to handle these parameters. Like @PathEntity, a URL template is tied to a domain entity, but now the request body is used to update the (detached) record. An example usage would be:


This controller method now only has to call the service method that updates the database. The code looks like this:


CRUD applications

The provided examples show the building blocks to reduce a CRUD application to almost no code beyond searching:
Create
The @RequestBody annotation combined with @Valid (see the first example) ensure that the controller only needs to save the record.
Read
The @PathEntity annotation in the second example already provides a loaded record, so the controller can simply return it. Only returning multiple records (i.e. searches) requires more code.
Update
The @RequestEntity annotation in the third example provides a detached, updated and optionally validated record. This includes partial updates The controller method only has to save it.
Delete
The @PathEntity annotation provides a record, so it can simply be removed.
As you can see, this means that implementing CRUD has become as trivial as calling your persistence layer. And as an added bonus, the more complex use cases are now also easier to implement: only the call to your business method is needed.

Conclusion


The examples in this article show that it is easy to extend the default Spring functionality to extract any information you want from the request. You can augment the existing functionality with, for example, JSR-303 validations. Or you can completely roll your own solution, including merging the request information with existing data. Combined with the generic Spring concept that any REST call is a method invocation, anything is possible. Your business needs are in control, not the technology.

No comments: