🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
When building REST APIs in Spring Boot, many developers directly return JPA entities in API responses.
This may seem easy, but it’s a bad practice because it can:
❌ Expose sensitive fields (Security risk)
❌ Cause lazy loading issues (Performance impact)
❌ Tightly couple database structure with the API
💡 Solution? Use DTOs (Data Transfer Objects) instead of entities in responses.
In this guide, you'll learn:
✅ Why exposing JPA entities is dangerous
✅ How DTOs improve API security and performance
✅ How to combine multiple entities into a single DTO
✅ A complete Spring Boot example with best practices
🚨 Problem: Exposing Entities Can Leak Sensitive Data
Let's say we have a User entity representing database records:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String email;
private String password; // 🚨 Sensitive data
private LocalDateTime createdAt;
// Getters and Setters
}
❌ Bad Practice: Returning Entities in API Response
If we expose the entity directly in a REST API, the response might look like this:
📌 GET /api/users Response:
{
"id": 1,
"username": "rajiv",
"email": "rajiv@example.com",
"password": "hashed_password_123", // 🚨 Exposing sensitive data
"createdAt": "2024-02-25T10:00:00"
}
❌ Problem: The API leaks password and createdAt, which should not be visible to users!
✅ Solution: Use DTOs to Hide Sensitive Fields
Instead of exposing the full entity, we create a DTO that only includes necessary fields.
public record UserDTO(Long id, String username, String email) { }
✔ Good Practice: Returning DTO Instead of Entity
📌 GET /api/users Response (Using DTOs):
{
"id": 1,
"username": "rajiv",
"email": "rajiv@example.com"
}
✅ No password or unnecessary fields
✅ Secure and optimized response
🔄 Advanced Use Case: Merging Data from Two Entities into a DTO
In real-world applications, we often need to fetch data from multiple tables.
Instead of making two separate API calls, we can merge fields from multiple entities into a single DTO.
Example: User + Address Relationship
@Entity
@Table(name = "addresses")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String street;
private String city;
private String country;
@OneToOne
@JoinColumn(name = "user_id")
private User user;
}
✅ Create a DTO That Merges User & Address
We can create a DTO that combines user details and address details into a single response.
public record UserAddressDTO(
Long id,
String username,
String email,
String street,
String city,
String country) { }
🔄 Convert Entities to DTO in the Service Layer
@Service
public class UserService {
private final UserRepository userRepository;
private final AddressRepository addressRepository;
public UserService(UserRepository userRepository, AddressRepository addressRepository) {
this.userRepository = userRepository;
this.addressRepository = addressRepository;
}
// Convert User & Address to a single DTO
private UserAddressDTO mapToDTO(User user, Address address) {
return new UserAddressDTO(
user.getId(),
user.getUsername(),
user.getEmail(),
address.getStreet(),
address.getCity(),
address.getCountry()
);
}
public UserAddressDTO getUserWithAddress(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User not found"));
Address address = addressRepository.findByUser(user)
.orElseThrow(() -> new RuntimeException("Address not found"));
return mapToDTO(user, address);
}
}
🖥️ Create a Controller to Return the Merged DTO
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}/details")
public ResponseEntity<UserAddressDTO> getUserWithAddress(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUserWithAddress(id));
}
}
✅ Optimized API Response (Merged DTO)
📌 GET /api/users/1/details Response:
{
"id": 1,
"username": "rajiv",
"email": "rajiv@example.com",
"street": "123 Main St",
"city": "Mumbai",
"country": "India"
}
🚀 Key Takeaways
✅ NEVER expose JPA entities in API responses
✅ Use DTOs (Java Records) to control API responses
✅ Use DTOs to merge multiple entities into a single response
✅ Reduce unnecessary API calls by sending combined data in one request
By following these best practices, your Spring Boot APIs will be more secure, maintainable, and optimized for performance. 🚀
💡 Next Steps
🔥 Optimize DTO Mapping → Use MapStruct for automatic DTO conversion
🔥 Secure Your API → Implement Spring Security for authentication
🔥 Boost API Performance → Use Spring Boot Caching
🔹 Enjoyed this article? Share it and help more developers write better Spring Boot APIs! 🚀
My Top and Bestseller Udemy Courses. The sale is going on with a 70 - 80% discount. The discount coupon has been added to each course below:
Build REST APIs with Spring Boot 4, Spring Security 7, and JWT
[NEW] Learn Apache Maven with IntelliJ IDEA and Java 25
ChatGPT + Generative AI + Prompt Engineering for Beginners
Spring 7 and Spring Boot 4 for Beginners (Includes 8 Projects)
Available in Udemy for Business
Building Real-Time REST APIs with Spring Boot - Blog App
Available in Udemy for Business
Building Microservices with Spring Boot and Spring Cloud
Available in Udemy for Business
Java Full-Stack Developer Course with Spring Boot and React JS
Available in Udemy for Business
Build 5 Spring Boot Projects with Java: Line-by-Line Coding
Testing Spring Boot Application with JUnit and Mockito
Available in Udemy for Business
Spring Boot Thymeleaf Real-Time Web Application - Blog App
Available in Udemy for Business
Master Spring Data JPA with Hibernate
Available in Udemy for Business
Spring Boot + Apache Kafka Course - The Practical Guide
Available in Udemy for Business
Comments
Post a Comment
Leave Comment