Spring Data REST simplifies the creation of RESTful APIs for Spring Data repositories. It eliminates boilerplate code and automatically exposes repository methods as REST endpoints. This guide demonstrates how to create a Spring Data REST application with PostgreSQL.
Project Setup
Dependencies
Add the following dependencies in your pom.xml
for a Maven project:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Spring Data REST -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<!-- PostgreSQL Driver -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
</dependencies>
Application Properties
Configure the PostgreSQL database in application.properties
or application.yml
:
# PostgreSQL Configuration
spring.datasource.url=jdbc:postgresql://localhost:5432/mydatabase
spring.datasource.username=myusername
spring.datasource.password=mypassword
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
Database Schema
Create a PostgreSQL database named mydatabase
:
CREATE DATABASE mydatabase;
Creating the Application
1. Define the Entity
Create an entity class Employee
representing the database table:
package com.example.springdatarest.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String role;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
2. Create the Repository
Spring Data REST will expose this repository as REST endpoints automatically.
package com.example.springdatarest.repository;
import com.example.springdatarest.entity.Employee;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
}
3. Bootstrapping the Application
Create the main application class:
package com.example.springdatarest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringDataRestApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDataRestApplication.class, args);
}
}
Testing the API
Default Endpoints
GET /employees
: Retrieve all employees.POST /employees
: Add a new employee.GET /employees/{id}
: Retrieve a specific employee by ID.PUT /employees/{id}
: Update an existing employee.DELETE /employees/{id}
: Delete an employee.
Sample Payload
POST Request to /employees
{
"firstName": "John",
"lastName": "Doe",
"role": "Developer"
}
Response
{
"id": 1,
"firstName": "John",
"lastName": "Doe",
"role": "Developer"
}
GET Request to /employees/1
{
"id": 1,
"firstName": "John",
"lastName": "Doe",
"role": "Developer"
}
Customizing the REST Endpoints
Changing Endpoint Path
Use the @RepositoryRestResource
annotation to customize endpoint paths:
@RepositoryRestResource(path = "staff")
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
}
Now, access employees at /staff
instead of /employees
.
Projection for Custom Views
You can define projections to customize the fields exposed by the API:
package com.example.springdatarest.projection;
import com.example.springdatarest.entity.Employee;
import org.springframework.data.rest.core.config.Projection;
@Projection(name = "employeeSummary", types = { Employee.class })
public interface EmployeeSummary {
String getFirstName();
String getLastName();
}
Usage
- GET
/employees?projection=employeeSummary
Error Handling
Spring Data REST provides default error handling. Customize it using @ControllerAdvice
for global exceptions:
package com.example.springdatarest.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleRuntimeException(RuntimeException ex) {
return "An error occurred: " + ex.getMessage();
}
}
Testing with Postman
Start your application using
SpringDataRestApplication
.Use Postman or curl to interact with the API:
GET
,POST
,PUT
, andDELETE
requests to/employees
.
Conclusion
With Spring Data REST, you can quickly expose repositories as RESTful APIs, reducing boilerplate and development time. By integrating with PostgreSQL, this guide demonstrates an end-to-end solution for managing database entities efficiently. Customize your endpoints and data exposure as needed for more control over your API.
More such articles: