Why do we have to copy-paste the same CRUD controller for every entity? Why do we have to write the same linking REST controllers for @OneToMany, @ManyToMany or @OneToOne relationships? With spring-rest-data you don’t have to do it anymore.
Table of contents
- Spring Data REST
- Basics
- Object creation
- Object linking
- Link removal
- Pagination
- Validation
- Conclusion
1. Spring Data REST
When you want to develop quick and straightforward REST API for some entities (with relations), you should check Spring-data-rest module. It’s built on top of Spring-data module which makes hypermedia-driven REST web services on top of Spring data repositories. It uses HAL as media type which makes consistent and easy way to hyperlink between all objects. If you are not familiar with this format, you can check Spring HATEOAS.
2. Basics
Let’s consider a spring-boot project which is so easy to do.
Maven dependencies:
Please note that for shortage purpose we used project Lombok for @Getter and @Setter. If you are not familiar with it, please check this out!
Spring boot main class
Application.properties
It will be used to say spring-boot that we want to setup Hibernate with H2.
Models
Is the @RestResource required annotation? No! If you don’t need anything more special that ‘/pet/owner’ endpoint, you do not have to write it. It may be used for customising the endpoint.
Repositories
What did we do? One project, two model classes, one relation, two interfaces without any implementation. You may ask what more? That’s it and it works. 🙂 You may ask what we have? Full CRUD REST API for Owner and Pet entity with linking API.
3. Object creation
We did not preload database so let’s create a Pet.
Response
And Owner
Response
4. Object linking
So let’s add pet to owner.
And check if the association was persisted.
From Pet’s side, let’s retrieve an owner/
Response
And from Owner’s side, we can retrieve pets.
Response
5. Link removal
We may also remove an association with:
6. Pagination
But what if we will have a simple application with many records? We may need some pagination. We may use javax.persistence.Query with bound pagination or Criteria API but it’s just a boilerplate code which repeats and repeats. With Spring-data-rest what we only need is… interface.
Let’s change our PetRepository.
In the meantime let’s load some records into the database to check the pagination.
Data.sql
Pagination request
Response
7. Validation
Let’s consider validation using org.springframework.validation.Validator. To make it fully work, we need to: implement validator, register it on Spring Data REST event.
There are eight different data REST events:
- BeforeCreateEvent
- AfterCreateEvent
- BeforeSaveEvent
- AfterSaveEvent
- BeforeLinkSaveEvent
- AfterLinkSaveEvent
- BeforeDeleteEvent
- AfterDeleteEvent
Validator implementation
Resource bundle (messages.properties)
Validator registration on “beforeCreate” event
Validation check
Response
8. Conclusion
As you can see, you can save your time by learning Spring Data REST. The code is clean and readable.
Be aware because as every generic solution – it’s not perfect. You can see the JIRA for issues. For more information check the Spring Data REST documentation.
For above code please check GitHub.