Spring Data REST
Spring Data REST takes a Spring Data repository and automatically exposes it as a fully navigable hypermedia REST API — no controllers, no service layer, no mapping code. It inspects every JpaRepository in your context and publishes CRUD endpoints that speak HAL (Hypertext Application Language), complete with paging, sorting, and discoverable links between resources.
It is a fantastic accelerator for admin tools and CRUD-heavy backends, and a poor fit when you need bespoke request/response shapes or business logic. This page shows both sides.
Adding the starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
With the starter on the classpath and a repository like the one below, you already have a working API:
public interface ProductRepository extends JpaRepository<Product, Long> {
}
Boot the app and GET http://localhost:8080/ returns the root resource listing every exported repository:
{
"_links": {
"products": {
"href": "http://localhost:8080/products{?page,size,sort}",
"templated": true
},
"profile": { "href": "http://localhost:8080/profile" }
}
}
The collection name is derived from the entity (Product → products). Each item gets a self link and links to its associations.
CRUD out of the box
Every standard verb is mapped automatically:
| HTTP | Path | Action |
|---|---|---|
GET | /products | Paged collection |
GET | /products/{id} | Single resource |
POST | /products | Create |
PUT / PATCH | /products/{id} | Replace / partial update |
DELETE | /products/{id} | Delete |
GET | /products/search | List exported query methods |
A GET /products/42 returns HAL, with _links letting a client walk to related resources:
{
"name": "Mechanical Keyboard",
"price": 89.99,
"_links": {
"self": { "href": "http://localhost:8080/products/42" },
"product": { "href": "http://localhost:8080/products/42" },
"category": { "href": "http://localhost:8080/products/42/category" }
}
}
Notice the entity id is not in the JSON body — it lives in the self link. Associations (here category) are exposed as their own linkable sub-resources rather than inlined.
Exposing query methods
Any derived query method on the repository is published under /search:
public interface ProductRepository extends JpaRepository<Product, Long> {
List<Product> findByCategory(@Param("category") String category);
}
GET /products/search/findByCategory?category=books
Tip: Use
@Paramon query-method arguments. Spring Data REST relies on it to map request parameters to method arguments — without it, parameter names may be lost after compilation.
Customising with @RepositoryRestResource
The defaults are conventions you can override. @RepositoryRestResource controls the exported path and link relation, and lets you hide methods or whole repositories.
@RepositoryRestResource(path = "items", collectionResourceRel = "items")
public interface ProductRepository extends JpaRepository<Product, Long> {
// Hide a single method from the REST API
@RestResource(exported = false)
@Override
void deleteById(Long id);
@RestResource(path = "by-category", rel = "by-category")
List<Product> findByCategory(@Param("category") String category);
}
path/collectionResourceRelrename the URL segment and HAL link key (/itemsinstead of/products).@RestResource(exported = false)removes a method — hereDELETEis disabled.- To hide an entire repository, annotate it with
@RepositoryRestResource(exported = false).
Projections — reshaping a single resource
By default the full entity is serialized. A projection is an interface that selects or computes a subset of fields, requested via ?projection=:
@Projection(name = "summary", types = Product.class)
public interface ProductSummary {
String getName();
BigDecimal getPrice();
// Computed (SpEL) property
@Value("#{target.name + ' (' + target.category.name + ')'}")
String getLabel();
}
GET /products/42?projection=summary
{
"name": "Mechanical Keyboard",
"price": 89.99,
"label": "Mechanical Keyboard (Peripherals)"
}
Excerpts — projections on the collection
An excerpt applies a projection automatically to every item in a collection so the list endpoint returns a lighter shape without a query parameter:
@RepositoryRestResource(excerptProjection = ProductSummary.class)
public interface ProductRepository extends JpaRepository<Product, Long> {
}
Now GET /products embeds the summary view for each item under _embedded.products, keeping list payloads small.
Note: Excerpts only apply to collection resources, not to the single-item endpoint. Requesting
/products/42still returns the full entity unless you add?projection=summary.
Configuration
Tune behaviour with the spring.data.rest.* properties:
spring:
data:
rest:
base-path: /api # all endpoints under /api/products
default-page-size: 20
max-page-size: 100
return-body-on-create: true
return-body-on-update: true
For finer control, implement RepositoryRestConfigurer:
@Configuration
public class RestConfig implements RepositoryRestConfigurer {
@Override
public void configureRepositoryRestConfiguration(
RepositoryRestConfiguration config, CorsRegistry cors) {
config.setBasePath("/api");
// Expose entity ids in the JSON body for this type
config.exposeIdsFor(Product.class);
}
}
When it shines vs when to hand-write controllers
| Use Spring Data REST when | Hand-write REST controllers when |
|---|---|
| Building an internal admin / CRUD console | You need custom DTO request/response shapes |
| The API maps closely to the entity model | Business logic must run on create/update |
| You want HATEOAS discoverability for free | The contract must be stable and decoupled from entities |
| Rapid prototyping over an existing schema | You need fine-grained authorization per operation |
Warning: Spring Data REST exposes your entities directly, leaking persistence concerns into the public contract. For external, versioned APIs prefer explicit controllers with DTOs and a mapping layer. Reserve Data REST for trusted, internal CRUD.
You can also mix the two: keep Data REST for the boring CRUD and add normal @RestController endpoints for the handful of operations that need real logic.