Building Java RESTful Web Services Using Spring Boot, Spring Data JPA, and MySQL [2025 Edition]
π Learn how to develop RESTful web services using Spring Boot, Spring Data JPA, and MySQL. Test APIs using Postman and implement CRUD operations with best practices.
For non-members, read this article for free on my blog: Building RESTful Web Services Using Spring Boot, Spring Data JPA, and MySQL.
πΉ Introduction: Why Build REST APIs Using Spring Boot?
Spring Boot is one of the most popular Java frameworks for building scalable and efficient RESTful APIs. Using Spring Data JPA and MySQL, we can create database-backed web services with minimal configuration.
π What You Will Learn
β
How to set up a Spring Boot project with MySQL.
β
How to create a REST API for CRUD operations.
β
How to use Spring Data JPA to interact with the database.
β
How to implement exception handling in a RESTful API.
β
How to test APIs using Postman.
I am a bestseller Udemy Instructor. Check out my top 10 Udemy courses with discounts: My Udemy Courses β Ramesh Fadatare.
π Step 1: Set Up the Spring Boot Project
We will use Spring Initializr to generate the Spring Boot project.
1οΈβ£ Go to Spring Initializr.
2οΈβ£ Select the following options:
- Project Type: Maven
- Language: Java
- Spring Boot Version: 3.x
- Group:
net.javaguides.usermanagement
- Artifact:
user-management
- Dependencies:
β Spring Web (for building REST APIs)
β Spring Data JPA (for database interaction)
β MySQL Driver (for connecting to MySQL)
β Lombok (to reduce boilerplate code)
3οΈβ£ Click Generate and download the project.
4οΈβ£ Extract the zip file and open it in IntelliJ IDEA or VS Code.
Create a Packaging Structure:
π Step 2: Configure MySQL Database
We need to configure MySQL as our database in the application.properties file.
π Open src/main/resources/application.properties
and add:
spring.application.name=user-management
spring.datasource.url=jdbc:mysql://localhost:3306/user_management
spring.datasource.username=root
spring.datasource.password=Password@123
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
π Explanation
βοΈ spring.datasource.url β Defines the database connection URL.
βοΈ spring.datasource.username & password β Credentials for MySQL.
βοΈ spring.jpa.hibernate.ddl-auto=update β Automatically updates the schema based on entity changes.
βοΈ spring.jpa.show-sql=true β Enables SQL query logging for debugging.
π Step 3: Create the User Entity
Spring Data JPA allows us to define database tables as Java classes using the @Entity
annotation.
π Create User.java
inside net.javaguides.usermanagement.entity
package net.javaguides.usermanagement.entity;
import jakarta.persistence.*;
import java.time.LocalDate;
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String email;
private LocalDate dateOfBirth;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public LocalDate getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(LocalDate dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
}
π Step 4: Create the User Repository
Spring Data JPA provides JpaRepository
, which includes methods for CRUD operations.
π Create UserRepository.java
inside net.javaguides.usermanagement.repository
package net.javaguides.usermanagement.repository;
import net.javaguides.usermanagement.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;public interface UserRepository extends JpaRepository<User, Long> {}
βοΈ Extends JpaRepository<User, Long>
β Provides built-in CRUD methods (save
, findById
, deleteById
, etc.).
π Step 5: Implement DTO and Mapper
Instead of exposing Entity classes, we use DTO (Data Transfer Object) to encapsulate and validate data.
π Create UserDto.java
inside net.javaguides.usermanagement.dto
package net.javaguides.usermanagement.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDate;
public record UserDto(
Long id,
String firstName,
String lastName,
String email,
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
LocalDate dateOfBirth
) {}
π Create UserMapper.java
inside net.javaguides.usermanagement.mapper
package net.javaguides.usermanagement.mapper;
import net.javaguides.usermanagement.dto.UserDto;
import net.javaguides.usermanagement.entity.User;
import org.springframework.stereotype.Component;
@Component
public class UserMapper {
public UserDto toDto(User user) {
return new UserDto(
user.getId(),
user.getFirstName(),
user.getLastName(),
user.getEmail(),
user.getDateOfBirth()
);
}
public User toEntity(UserDto userDto) {
User user = new User();
user.setId(userDto.id());
user.setFirstName(userDto.firstName());
user.setLastName(userDto.lastName());
user.setEmail(userDto.email());
user.setDateOfBirth(userDto.dateOfBirth());
return user;
}
}
π Step 6: Implement the Service Layer
π Create ResourceNotFoundException.java
inside net.javaguides.usermanagement.exception
package net.javaguides.usermanagement.exception;
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
π Create UserService.java
inside net.javaguides.usermanagement.service
package net.javaguides.usermanagement.service;
import net.javaguides.usermanagement.dto.UserDto;
import java.util.List;
public interface UserService {
UserDto createUser(UserDto userDto);
UserDto getUserById(Long id);
List<UserDto> getAllUsers();
UserDto updateUser(Long id, UserDto userDto);
void deleteUser(Long id);
}
π Create UserServiceImpl.java
inside net.javaguides.usermanagement.service.impl
π Create UserServiceImpl.java
inside net.javaguides.usermanagement.service.impl
package net.javaguides.usermanagement.service.impl;
import net.javaguides.usermanagement.dto.UserDto;
import net.javaguides.usermanagement.entity.User;
import net.javaguides.usermanagement.exception.ResourceNotFoundException;
import net.javaguides.usermanagement.mapper.UserMapper;
import net.javaguides.usermanagement.repository.UserRepository;
import net.javaguides.usermanagement.service.UserService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
public UserServiceImpl(UserRepository userRepository, UserMapper userMapper) {
this.userRepository = userRepository;
this.userMapper = userMapper;
}
@Override
public UserDto createUser(UserDto userDto) {
User user = userMapper.toEntity(userDto);
User savedUser = userRepository.save(user);
return userMapper.toDto(savedUser);
}
@Override
public UserDto getUserById(Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + id));
return userMapper.toDto(user);
}
@Override
public List<UserDto> getAllUsers() {
return userRepository.findAll()
.stream()
.map(userMapper::toDto)
.collect(Collectors.toList());
}
@Override
public UserDto updateUser(Long id, UserDto userDto) {
User user = userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + id));
user.setFirstName(userDto.firstName());
user.setLastName(userDto.lastName());
user.setEmail(userDto.email());
user.setDateOfBirth(userDto.dateOfBirth());
User updatedUser = userRepository.save(user);
return userMapper.toDto(updatedUser);
}
@Override
public void deleteUser(Long id) {
if (!userRepository.existsById(id)) {
throw new ResourceNotFoundException("User not found with id: " + id);
}
userRepository.deleteById(id);
}
}
Now that we have our User entity, DTO, service layer, and repository, we need to create a REST Controller to expose CRUD endpoints for managing users.
π Step 7: Implement the REST Controller
We will create a UserController to handle HTTP requests.
π Create UserController.java
inside net.javaguides.usermanagement.controller
package net.javaguides.usermanagement.controller;
import net.javaguides.usermanagement.dto.UserDto;
import net.javaguides.usermanagement.service.UserService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
// Create User
@PostMapping
public ResponseEntity<UserDto> createUser(@RequestBody UserDto userDto) {
return ResponseEntity.ok(userService.createUser(userDto));
}
// Get User by ID
@GetMapping("/{id}")
public ResponseEntity<UserDto> getUserById(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUserById(id));
}
// Get All Users
@GetMapping
public ResponseEntity<List<UserDto>> getAllUsers() {
return ResponseEntity.ok(userService.getAllUsers());
}
// Update User
@PutMapping("/{id}")
public ResponseEntity<UserDto> updateUser(
@PathVariable Long id,
@RequestBody UserDto userDto) {
return ResponseEntity.ok(userService.updateUser(id, userDto));
}
// Delete User
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.noContent().build();
}
}
π Explanation of UserController.java
βοΈ @RestController
β Marks this class as a Spring REST Controller.
βοΈ @RequestMapping("/api/users")
β All API routes start with /api/users
.
βοΈ @PostMapping
β Creates a new user.
βοΈ @GetMapping("/{id}")
β Retrieves a user by ID.
βοΈ @GetMapping
β Fetches all users.
βοΈ @PutMapping("/{id}")
β Updates an existing user.
βοΈ @DeleteMapping("/{id}")
β Deletes a user.
π Step 8: Run the Spring Boot Application
π Run the application using the following command:
mvn spring-boot:run
π The server should start at:
π http://localhost:8080
π Step 9: Test the APIs Using Postman
β 1. Create a New User (POST Request)
π POST Request URL:
http://localhost:8080/api/users
π Request Body (JSON Format)
{
"firstName": "Ramesh",
"lastName": "Fadatare",
"email": "ramesh.fadatare@example.com",
"dateOfBirth": "1991-08-15"
}
π Expected Response (201 Created)
{
"id": 2,
"firstName": "Ramesh",
"lastName": "Fadatare",
"email": "ramesh.fadatare@example.com",
"dateOfBirth": "1991-08-15"
}
β 2. Get All Users (GET Request)
β 3. Get User by ID (GET Request)
π GET Request URL:
http://localhost:8080/api/users/1
β 4. Update User (PUT Request)
π PUT Request URL:
http://localhost:8080/api/users/1
π Request Body (JSON Format)
Updating email and dateOfBirth fields.
{
"firstName": "Ramesh",
"lastName": "Fadatare",
"email": "ramesh.fadatare@gmail.com",
"dateOfBirth": "1991-08-25"
}
π Expected Response (200 OK)
{
"firstName": "Ramesh",
"lastName": "Fadatare",
"email": "ramesh.fadatare@gmail.com",
"dateOfBirth": "1991-08-25"
}
β 5. Delete User (DELETE Request)
π DELETE Request URL:
http://localhost:8080/api/users/1
π Expected Response (204 No Content)
(No content, meaning the user was deleted successfully)
π― Summary: What We Achieved
βοΈ Set up a Spring Boot project with MySQL.
βοΈ Created a User entity, DTO, and Mapper.
βοΈ Implemented Spring Data JPA repository.
βοΈ Developed a RESTful API with CRUD operations.
βοΈ Tested the APIs using Postman.
π Next Steps
Exception Handling in Spring Boot Application [2025 Edition]
π Congratulations! You have successfully built RESTful APIs with Spring Boot and MySQL! ππ₯
I am a bestseller Udemy Instructor. Check out my top 10 Udemy courses with discounts: My Udemy Courses β Ramesh Fadatare.