# End-to-End Guide to Spring Data REST with PostgreSQL!

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:

```java
<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`](http://application.properties) or `application.yml`:

```java
# 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`:

```java
CREATE DATABASE mydatabase;
```

---

## **Creating the Application**

### **1\. Define the Entity**

Create an entity class `Employee` representing the database table:

```java
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.

```java
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:

```java
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`

```java
{
  "firstName": "John",
  "lastName": "Doe",
  "role": "Developer"
}
```

#### **Response**

```java
{
  "id": 1,
  "firstName": "John",
  "lastName": "Doe",
  "role": "Developer"
}
```

#### **GET Request to** `/employees/1`

```java
{
  "id": 1,
  "firstName": "John",
  "lastName": "Doe",
  "role": "Developer"
}
```

---

## **Customizing the REST Endpoints**

### **Changing Endpoint Path**

Use the `@RepositoryRestResource` annotation to customize endpoint paths:

```java
@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:

```java
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:

```java
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**

1. Start your application using `SpringDataRestApplication`.
    
2. Use **Postman** or **curl** to interact with the API:
    
    * `GET`, `POST`, `PUT`, and `DELETE` 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:**

[**medium.com/techwasti**](https://medium.com/techwasti)

[**youtube.com/@maheshwarligade**](https://www.youtube.com/@maheshwarligade)

[**techwasti.com/series/spring-boot-tutorials**](https://techwasti.com/series/spring-boot-tutorials)

[**techwasti.com/series/go-language**](https://techwasti.com/series/go-language)
