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:

@RequestMapping(value = "/tasks", produces = "application/hal+json")
public class TaskController {

    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.