Spring Data REST combines the features of Spring Data with Spring HATEOAS to make it easy to build hypermedia-driven REST APIs on top of Spring Data repositories. The basic functionality provided out of the box creates and exposes simple REST endpoints for performing CRUD operations on Spring Data repositories. For a lot of use cases, this is entirely enough functionality to meet your needs. In other cases, you need to extend the REST API to include additional functionality that isn’t provided by Spring Data REST and it can be difficult to determine exactly how to do this. In this blog post, I show you how to augment a Spring Data REST API with additional endpoints to turn a basic CRUD API into a full featured web service.
Basic Spring Data REST
This blog assumes you are using Spring Data REST. If you aren’t using it
yet, don’t worry. It’s fairly easy to get started. If you are using Spring
Boot simply add the spring-boot-starter-data-rest
dependency to your
project and create a Spring Data repository. In this example, I am using
JPA for my data repository, and I also include the Spring Data REST HAL
explorer that allows us to interact with the API created by Spring Data
REST.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
runtimeOnly 'org.springframework.data:spring-data-rest-hal-explorer'
}
With these dependencies in place, declaring a Spring Data repository is all you need to do to create a full-featured HAL API exposing the repository over REST:
public interface TaskRepository extends JpaRepository<Task, UUID> {
}
You can run your application and view the API using HAL explorer by
navigating to http://localhost:8080
. Spring Data REST will have
automatically scanned the repository and created endpoints that are
exposed as a REST API.
If you are having trouble getting this working, refer to this Baeldung tutorial and the Spring Data REST docs.
What you get from Spring Data REST
Spring Data REST automatically creates endpoints based on the
JpaRepository
in your application. In particular, it creates endpoints
for the tasks
resource that follow typical REST conventions:
localhost:8080\tasks\
- This endpoint exposes the tasks collection.
- Use HTTP GET to list all tasks.
- Use HTTP POST to create a new task.
localhost:8080\tasks\<id>
- This endpoint exposes a single task collection.
- Use HTTP GET to fetch the details of a task.
- Use HTTP POST to update an existing task.
Extending Spring Data REST
To extend this API, you can create a REST Controller with endpoints that provide additional features for operating on tasks. For example, to add a REST endpoint for cancelling a task, you can create the following Spring MVC controller:
@RestController
@RequestMapping(value = "/tasks", produces = "application/hal+json")
public class TaskController {
@PutMapping("/{id}/cancel")
public EntityModel<Task> cancel(@PathVariable UUID id) {
// todo
}
}
This MVC Controller is annotated with @RestController
and
@RequestMapping
. The RequestMapping
annotation uses the same route
(/tasks
) that was automatically created by Spring Data REST. This makes
it appear like a seamless extension to the REST API. The @RequestMapping
annotation also includes the parameter produces = application/hal+json
.
This parameter serializes the return value from the endpoint using the
same serialization protocol used by Spring Data REST.
And there you have it, extending a Spring Data REST API can be done fairly simply by creating a controller with the same path that produces the same response format. This makes the controller appear as a seamless addition to the automatically created Spring Data REST API and allows you to augment your Spring Data REST API with additional functionality.