Spring Data Rest with MySQL database [2021]





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

Build spring boot REST API with hibernate

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

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 and password 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



Bushan Sirgur

Hey guys, I am Bushan Sirgur from Banglore, India. Currently, I am working as an Associate project in an IT company.

This Post Has One Comment

  1. mridul

    you did not provide controller class

Leave a Reply