Spring Boot – Building REST APIs with HATEOAS
Last Updated :
22 Aug, 2024
In this article, we will explore how to build RESTful APIs using the Spring Boot with HATEOAS (Hypermedia as the Engine of Application State). HATEOAS is the key component of the REST application architecture, where each resource not only provides the data but also includes links to other actions that can be performed on the resource. This approach allows the clients to navigate through the application using these links, making the API more dynamic and discoverable.
HATEOAS in Spring Boot
HATEOAS is the concept within REST that enables the client to interact with the RESTful service entirely through hyperlinks provided dynamically by the service itself. It means the client does not need to hardcode the URIs of the resource but can discover them at runtime.
In Spring Boot, HATEOAS can be implemented using the spring-boot-starter-hateoas dependency which allows the easy creation of hypermedia links and resources. With HATEOAS each resource representation returned by the server can contain the links to related resources or actions that the client can follow.
Implementation to Build REST APIs with HATEOAS in Spring Boot
Step 1: Create a new Spring Boot Project.
Create a new Spring Boot project using IntelliJ Idea. Choose the below options:
- Name: Spring-HATEOAS-Demo
- Language: Java
- Type: Maven
- Packaging: Jar
Click on the Next button.
Step 2: Add the Dependencies
Add the following dependencies into the Spring Boot project. click on the create button to create the project.
Step 3: Project Structure
Once created the project, the file structure looks like:
Step 4: Configure Application Properties
Open the application.properties file and add the following configuration:
spring.application.name=Spring-HATEOAS-Demo
spring.datasource.url=jdbc:mysql://localhost:3306/employee_db
spring.datasource.username=root
spring.datasource.password=mypassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
Step 5: Create the Employee Entity
Create the Employee Entity class represents the database table structure of the Spring Boot project.
Java
package com.gfg.springhateoasdemo;
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 name;
private String role;
// Constructors
public Employee() {}
public Employee(String name, String role) {
this.name = name;
this.role = role;
}
// Getters and Setters
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 String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
Step 6: Create the EmployeeRepository Interface
Now create the EmployeeRepository class can be extends JpaRepository to provide the CRUD operations.
Java
package com.gfg.springhateoasdemo;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
Step 7: Create the EmployeeService Class
Now create the EmployeeService class contains the business logic for the CRUD operations of the project.
Java
package com.gfg.springhateoasdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public Employee createEmployee(Employee employee) {
return employeeRepository.save(employee);
}
public Employee getEmployeeById(Long id) {
return employeeRepository.findById(id).orElse(null);
}
public List<Employee> getAllEmployees() {
return employeeRepository.findAll();
}
public Employee updateEmployee(Long id, Employee employeeDetails) {
Employee employee = getEmployeeById(id);
if (employee != null) {
employee.setName(employeeDetails.getName());
employee.setRole(employeeDetails.getRole());
return employeeRepository.save(employee);
}
return null;
}
public void deleteEmployee(Long id) {
employeeRepository.deleteById(id);
}
}
Step 8: Create the EmployeeController Class
Create the EmployeeController class handles the HTTP requests and adds the HATEOAS links of the application endpoints.
Java
package com.gfg.springhateoasdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
@RestController
@RequestMapping("/employees")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@PostMapping
public EntityModel<Employee> createEmployee(@RequestBody Employee employee) {
Employee createdEmployee = employeeService.createEmployee(employee);
return toHateoasEntityModel(createdEmployee);
}
@GetMapping("/{id}")
public EntityModel<Employee> getEmployee(@PathVariable Long id) {
Employee employee = employeeService.getEmployeeById(id);
return toHateoasEntityModel(employee);
}
@GetMapping
public List<Employee> getAllEmployees() {
return employeeService.getAllEmployees();
}
@PutMapping("/{id}")
public EntityModel<Employee> updateEmployee(@PathVariable Long id, @RequestBody Employee employeeDetails) {
Employee updatedEmployee = employeeService.updateEmployee(id, employeeDetails);
return toHateoasEntityModel(updatedEmployee);
}
@DeleteMapping("/{id}")
public void deleteEmployee(@PathVariable Long id) {
employeeService.deleteEmployee(id);
}
private EntityModel<Employee> toHateoasEntityModel(Employee employee) {
Link selfLink = linkTo(methodOn(EmployeeController.class).getEmployee(employee.getId())).withSelfRel();
Link allEmployeesLink = linkTo(methodOn(EmployeeController.class).getAllEmployees()).withRel("all-employees");
return EntityModel.of(employee, selfLink, allEmployeesLink);
}
}
Step 9: Main Class
No changes are required in the main class.
Java
package com.gfg.springhateoasdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HateoasApplication {
public static void main(String[] args) {
SpringApplication.run(HateoasApplication.class, args);
}
}
pom.xml file
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 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>3.2.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>Spring-HATEOAS-Demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Spring-HATEOAS-Demo</name>
<description>Spring-HATEOAS-Demo</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</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-hateoas</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>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 10: Run the Application
Once completed the project, it will start and run at port 8080.
Step 11: Testing the Endpoints
1. Create Employee
POST http://localhost:8080/employees
2. Get All Employees
GET http://localhost:8080/employees
3. Get Employee by ID
GET http://localhost:8080/employees/1
4. Update Employee
PUT http://localhost:8080/employees/1
5. Delete Employee
DELETE http://localhost:8080/employees/1
By following these steps, we can test each of the CRUD operations for the Spring Boot application with HATEOAS and MySQL. Each request should be conform to the structure and links defined in the example project.
Similar Reads
Spring Boot Integration With MySQL as a Maven Project
Spring Boot is trending and it is an extension of the spring framework but it reduces the huge configuration settings that need to be set in a spring framework. In terms of dependencies, it reduces a lot and minimized the dependency add-ons. It extends maximum support to all RDBMS databases like MyS
4 min read
A Guide to RestClient in Spring Boot
In Spring Boot applications, external services often need to be communicated via REST APIs. Traditionally, RestTemplate was used for this purpose, but it is now considered a legacy approach. Starting from Spring Framework 6.1 and Spring Boot 3.2, RestClient has been introduced as a modern alternativ
9 min read
Securing REST APIs with Spring Security
In Spring Boot applications, securing the REST APIs is a critical aspect of developing secure and robust applications. REST APIs are commonly used to expose functionalities to external systems, mobile applications, and web applications. Without proper security measures, these APIs can become targets
8 min read
Building Real-Time Applications with Java Spring Boot and WebSocket
Real-time applications are those that require immediate response and interaction with the users and they can often involve data updates or notifications without requiring the page refresh. Java Spring Boot along with the WebSocket can provide a powerful framework for building such applications. WebS
12 min read
Best Practices while Making Rest APIs in Spring Boot Application
API, or Application Programming Interface, is a communication gateway between frontend and backend code. A robust API is crucial for ensuring uninterrupted functionality. In this article, we will discuss how to achieve robustness in our REST API within the Spring Boot application. Rules : Use JSON a
7 min read
Spring Boot â REST API Documentation using Swagger
REST stands for Representational State Transfer. REST is an architectural design pattern that defines constraints that are used in web service development. Swagger is a framework in which we can test our REST APIs for different HTTP requests i.e. : GETPOSTPUTDELETEIn this article, we will be discuss
4 min read
Spring Boot - REST API Documentation using OpenAPI
For any application, API documentation is essential for both users and developers. How to use an API, what will be the request body, and what will the API's response be? API documentation is the answer to all of these questions, springdoc-openapi is a Java library that automates the generation of th
4 min read
How to Generate Spring Boot REST Client with Swagger?
Spring Boot is a powerful framework for building Java applications, particularly RESTful web services. When developing the REST APIs, it can be crucial to provide documentation that is both user-friendly and interactive. Swagger is an open-source that simplifies this by generating the API documentat
6 min read
How to Create a REST API using Java Spring Boot?
Representational State Transfer (REST) is a software architectural style that defines a set of constraints for creating web services. RESTful web services allow systems to access and manipulate web resources through a uniform and predefined set of stateless operations. Unlike SOAP, which exposes its
4 min read
Easiest Way to Create REST API using Spring Boot
Spring Boot is a powerful framework that makes it easy to create RESTful APIs. Creating a REST API using Spring Boot is one of the fastest and simplest ways to develop scalable and production-ready web services. Spring Boot simplifies REST API development by providing built-in features such as autom
11 min read