Building RESTful Web Services Using Spring Boot, Spring Data JPA, and MySQL

🚀 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.

🔹 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.

🚀 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:

Building RESTful Web Services Using Spring Boot, Spring Data JPA, and MySQL

🚀 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

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.
✔️ @PostMappingCreates a new user.
✔️ @GetMapping("/{id}")Retrieves a user by ID.
✔️ @GetMappingFetches 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"
}
Building RESTful Web Services Using Spring Boot, Spring Data JPA, and MySQL

✅ 2. Get All Users (GET Request)

Building RESTful Web Services Using Spring Boot, Spring Data JPA, and MySQL

✅ 3. Get User by ID (GET Request)

📌 GET Request URL:

http://localhost:8080/api/users/1
Building RESTful Web Services Using Spring Boot, Spring Data JPA, and MySQL

✅ 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)

Building RESTful Web Services Using Spring Boot, Spring Data JPA, and MySQL

🎯 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

🎉 Congratulations! You have successfully built RESTful APIs with Spring Boot and MySQL! 🚀🔥

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare