Hey guys in this post, we will discuss how to create spring boot REST API using Spring Data Rest module and we will connect it to the MySQL database. We will create a simple employee management system, and it has the following rest end points
Table of Contents
Spring data REST
Spring Data REST builds on top of the Spring Data repositories and automatically exports those as REST resources. It leverages hypermedia to let clients automatically find functionality exposed by the repositories and integrate these resources into related hypermedia-based functionality.
Further read on Spring Data Rest at https://docs.spring.io/spring-data/rest/docs/current/reference/html/#reference
Development steps
Following are the development steps to create the spring boot REST API with Spring Data Rest
Create spring boot project
There two different ways to create spring boot project
- Create spring boot project using Spring initializr
- Create spring boot project with spring tool suite [STS]
Add maven dependencies
While creating the project make sure to add the following dependencies
- Spring web
- Spring data jpa
- Rest repositories
- Mysql driver
- Spring boot devtools
following is the pom.xml
file after adding all the dependencies
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>in.bushansirgur</groupId>
<artifactId>springdatarest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>employeerestapi</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Configure database
Open application.properties
and add the following contents
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springbootapps?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=jan@2021
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.data.rest.base-path=/api/v1
spring.jpa.hibernate.ddl-auto=update
Make sure to change the database
username
andpassword
as per your installation
Create entity class
Now let’s create a jpa entity class Employee.java
inside the package in.bushansirgur.springdatarest.entity
and add the following contents
package in.bushansirgur.springdatarest.entity;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private BigDecimal salary;
private Integer age;
@Column(name="created_at", nullable = false, updatable = false)
@CreationTimestamp
private Date createdOn;
@Column(name="updated_at")
@UpdateTimestamp
private Date updatedOn;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getSalary() {
return salary;
}
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Date createdOn) {
this.createdOn = createdOn;
}
public Date getUpdatedOn() {
return updatedOn;
}
public void setUpdatedOn(Date updatedOn) {
this.updatedOn = updatedOn;
}
}
Create JPA repository
Now let’s create JPA repository EmployeeRepository.java
inside the package in.bushansirgur.springdatarest.repository
and add the following contents
package in.bushansirgur.springdatarest.repository;
import in.bushansirgur.springdatarest.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RestResource;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
@RestResource(path = "names")
List<Employee> findByName(@RequestParam("name") String name);
}
Create configuration class
By default spring data rest does not expose ids in the response. But we need ids for several reasons like while retreiving the single employee, updating employee and deleting employee. So we can override the existing implementation by creating a configuration class MyRepositoryRestConfigurerAdapter.java
inside the in.bushansirgur.springdatarest.config
package and add the following contents
package in.bushansirgur.springdatarest.configuration;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.metamodel.Type;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
@Configuration
public class MyRepositoryRestConfigurerAdapter implements RepositoryRestConfigurer {
@Autowired
private EntityManager entityManager;
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(entityManager.getMetamodel().getEntities().stream()
.map(Type::getJavaType)
.toArray(Class[]::new));
}
}
That’s it, now the spring data rest automatically exposes the rest end points for us.
Test rest end points
- GET
/api/v1/employees
- GET
/api/v1/employees/9
- POST
/api/v1/employees
- PUT
/api/v1/employees/9
- PATCH
/api/v1/employees/9
- DELETE
/api/v1/employees/9
How does it work?
Spring data rest will automatically exposes the rest end points based on the entity name. It will pluralize the entity name and convert the first character to lower case (Eg: Entity name is Student, it will convert it to students, similarly for Employee, it will convert it to employees).
You can customize the rest end points, if you want by adding @RepositoryRestResource
annotation at the top of Repository interface.
@RepositoryRestResource(path="/listemployees")
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
now the rest URL’s will be /api/v1/listemployees
Further read on customizing the Spring data rest at https://docs.spring.io/spring-data/rest/docs/current/reference/html/#customizing-sdr
JPA query methods
Let’s see how JPA query method will work and what will the rest end point for query methods. Inside the repository we have added the query method for retrieving the list of employees based on employee name
List<Employee> findByName(@RequestParam("name") String name);
The method in the preceding example is exposed at http://localhost:8080/api/v1/employees/search/findByName
All query method resources are exposed under the
search
resource.
- GET
/api/v1/employees/search/findByName
we can even override the rest end point for jpa query methods as well using @RestResource
annotation
@RestResource(path = "names")
List<Employee> findByName(@RequestParam("name") String name);
with this, now the rest end point will be /api/v1/employees/search/names
Further read at https://docs.spring.io/spring-data/rest/docs/current/reference/html/#customizing-sdr.configuring-the-rest-url-path
That’s all about Spring Data Rest, hope you understand the high level overview of Spring data rest. Let me know in the comment section if you have any queries
you did not provide controller class