Introduction to Spring Data REST
Save coding time when building microservices by exposing Spring Data repositories as a REST API. Learn how in this tutorial.
Join the DZone community and get the full member experience.
Join For FreeThis tutorial on Spring Data REST shows how Spring Data repositories can be exposed as a REST API. It's a really interesting idea, and can save you a lot of boilerplate code building microservices.
Spring Boot makes it easy to create a Spring Data REST starter project using Spring Initializr –
Spring Initializr – Spring Boot JPA Microservice.
I'm using Spring Boot 2.0.0, and the HAL Browser to quickly demonstrate REST API.
Download, expand and import into your IDE –
Expanded Spring Boot Project.
Code
For a quick start, the code is available on GitHub.
Let’s keep this simple and use the classes from my parkrunpb project.
The starting point is the pom.xml –
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javabullets.springdata</groupId>
<artifactId>jparest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>jparest</name>
<description>Spring Data Rest Example</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<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.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</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>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
So we have our JPA object –
package com.javabullets.springdata.jparest;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class ParkrunCourse {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String courseName;
private String url;
private Long averageTime;
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Long getAverageTime() {
return averageTime;
}
public void setAverageTime(Long averageTime) {
this.averageTime = averageTime;
}
}
I'm using JPARepository –
package com.javabullets.springdata.jparest;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
public interface ParkrunCourseRepository extends JpaRepository<ParkrunCourse, Long> {
}
And a script to ensure the data is preloaded – stored in (src\main\resources\import.sql) –
INSERT INTO PARKRUN_COURSE(ID, COURSE_NAME, URL, AVERAGE_TIME) VALUES (1, 'Inverness', 'http://www.parkrun.org.uk/inverness/', 1582);
INSERT INTO PARKRUN_COURSE(ID, COURSE_NAME, URL, AVERAGE_TIME) VALUES (2, 'Aberdeen', 'http://www.parkrun.org.uk/aberdeen/', 1586);
INSERT INTO PARKRUN_COURSE(ID, COURSE_NAME, URL, AVERAGE_TIME) VALUES (3, 'Dundee(Camperdown)', 'http://www.parkrun.org.uk/camperdown/', 1752);
INSERT INTO PARKRUN_COURSE(ID, COURSE_NAME, URL, AVERAGE_TIME) VALUES (4, 'St Andrews', 'http://www.parkrun.org.uk/standrews/', 1669);
INSERT INTO PARKRUN_COURSE(ID, COURSE_NAME, URL, AVERAGE_TIME) VALUES (5, 'Perth', 'http://www.parkrun.org.uk/perth/', 1620);
INSERT INTO PARKRUN_COURSE(ID, COURSE_NAME, URL, AVERAGE_TIME) VALUES (6, 'Edinburgh', 'http://www.parkrun.org.uk/edinburgh/', 1523);
Running the Code
Run the code using the Maven wrapper – mvnw –
mvnw spring-boot:run
We can then access the HALBrowser on http://localhost:8080/browser/index.html#http://localhost:8080/parkrunCourses -
Spring Data REST – HALBrowser.
The response body returns all the parkrunCourse. You can also do GET, POST, PUT, PATCH and DELETE.
A good trick is to use the browser integrated SQL editor for the H2 database. I covered this in my Spring Boot security tutorial.
hal+json Media Type
Spring Data JPA allows you to make calls as JSON or hal+json. The purpose of hal+json makes it easier to navigate API’s following links. The HALBrowser is great for quickly checking your API.
This example shows how a spring data repository can easily be exposed as a REST API. My next post will look at the practicality of this approach, and what restrictions you might want to apply to your API.
Published at DZone with permission of Martin Farrell, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Auto-Scaling Kinesis Data Streams Applications on Kubernetes
-
Micro Frontends on Monorepo With Remote State Management
-
Five Java Books Beginners and Professionals Should Read
-
Web Development Checklist
Comments