HelloKoding

Practical coding guides

Spring Boot REST API Example with Spring Data REST

This tutorial will walk you through the steps of creating a REST API Example in Spring Boot with Spring Data REST, Spring Data JPA and Hibernate One To Many Relationship

What you’ll need

  • JDK 1.7+
  • Maven 3+
  • MySQL Server 5.6+

Stack

  • Spring Boot
  • Spring Data REST
  • Spring Data JPA
  • MySQL

Init project structure and dependencies

Project structure

├── src
│   └── main
│       ├── java
│       │   └── com
│       │       └── hellokoding
│       │           └── restfulapi
│       │               ├── Application.java
│       │               ├── model
│       │               │   ├── Book.java
│       │               │   └── BookCategory.java
│       │               └── repository
│       │                   ├── BookCategoryRepository.java
│       │                   └── BookRepository.java
│       └── resources
│           └── application.properties
└── pom.xml

Project dependencies

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.hellokoding.springdatarest</groupId>
	<artifactId>restfull.onetomany</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.4.RELEASE</version>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-rest</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</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>

Define JPA Entity and Repository

Create domain objects

BookCategory.java

package com.hellokoding.restfulapi.model;

import javax.persistence.*;
import java.util.Set;

@Entity
@Table(name = "book_category")
public class BookCategory {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String name;

    @OneToMany(mappedBy = "bookCategory", cascade = CascadeType.ALL)
    private Set<Book> books;

    public BookCategory(){

    }

    public BookCategory(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Book> getBooks() {
        return books;
    }

    public void setBooks(Set<Book> books) {
        this.books = books;
    }

    @Override
    public String toString() {
        String result = String.format(
                "Category[id=%d, name='%s']%n",
                id, name);
        if (books != null) {
            for(Book book : books) {
                result += String.format(
                        "Book[id=%d, title='%s']%n",
                        book.getId(), book.getTitle());
            }
        }

        return result;
    }
}

Book.java

package com.hellokoding.restfulapi.model;

import javax.persistence.*;

@Entity
public class Book{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String title;

    private String description;

    @ManyToOne
    @JoinColumn(name = "book_category_id")
    private BookCategory bookCategory;

    public Book() {

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public BookCategory getBookCategory() {
        return bookCategory;
    }

    public void setBookCategory(BookCategory bookCategory) {
        this.bookCategory = bookCategory;
    }
}

Spring Data Repository

Spring Data JPA and Spring Data Rest will auto create some helper methods and RESTful APIs. For this example, we only need to extend JpaRepository

BookCategoryRepository.java

package com.hellokoding.restfulapi.repository;

import com.hellokoding.restfulapi.model.BookCategory;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BookCategoryRepository extends JpaRepository<BookCategory, Integer>{
}

BookRepository.java

package com.hellokoding.restfulapi.repository;

import com.hellokoding.restfulapi.model.Book;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BookRepository extends JpaRepository<Book, Integer>{
}

Config and Run

Application Properties

application.properties

spring.datasource.url=jdbc:mysql://localhost/test?useSSL=false
spring.datasource.username=root
spring.datasource.password=hellokoding
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.initialization-mode=always
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database-platform=org.hibernate.dialect.MySQL57Dialect
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true

Run the application

Application.java

package com.hellokoding.restfulapi;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Type mvn clean spring-boot:run on terminal at the project root directory to run

Test the application

Create a new category

curl -i -X POST -H "Content-Type:application/json" -d "{\"name\":\"Cat 1\"}" http://localhost:8080/bookCategories

Create a new book

curl -i -X POST -H "Content-Type:application/json" -d "{\"title\" : \"Hello Koding\", \"description\": \"Simple coding examples and tutorials\"}" http://localhost:8080/books 

Assign book to category

curl -i -X PUT -H "Content-Type:text/uri-list" -d "http://localhost:8080/bookCategories/1" http://localhost:8080/books/1/bookCategory 

Source code

https://github.com/hellokoding/hellokoding-courses/blob/master/springboot-examples/springdatarest-mysql-one-to-many

Follow HelloKoding