Spring Boot Rest API
Spring Boot Rest API
If you are working with Spring Boot REST API, here are the most important topics you
should focus on:
REST vs SOAP
Status Codes (200, 201, 400, 401, 403, 404, 500, etc.)
JSON vs XML
@RestController vs @Controller
1/4
Path Variables ( @PathVariable ) and Query Parameters ( @RequestParam )
Custom Validators
2/4
Securing REST APIs with Spring Security
OAuth2 Authorization
3/4
Setting up Swagger ( springdoc-openapi )
Interview-Specific Questions
1. Difference between @RestController and @Controller
Next Steps?
Do you need code examples or in-depth explanations on any of these topics? 😊
4/4
Core Java Best Practices
I'll provide a detailed explanation of each topic related to Spring Boot Basics.
Key Features:
1/6
Feature Spring Framework Spring Boot
Microservices Used but requires extra setup Built specifically for microservices
development
Production Features Requires additional setup for Has built-in monitoring, logging, and
monitoring, logging Actuator
Reduces configuration
2. Microservices Ready:
3. Auto Configuration:
4. Embedded Servers:
5. Production-Ready:
Uses @Service
Uses @Repository
Spring Boot CLI → Allows running Spring Boot apps with minimal code
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
3/6
return userService.getUserById(id);
}
}
java
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
1️⃣ @SpringBootApplication
Example:
java
@SpringBootApplication
public class MyApp {
4/6
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
2️⃣ @Component
Example:
java
@Component
public class MyComponent {
public void doSomething() {
System.out.println("Component is working!");
}
}
3️⃣ @Service
Example:
java
@Service
public class UserService {
public String getUser() {
return "John Doe";
}
}
5/6
4️⃣ @Repository
Example:
java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
🎯 Summary
Annotation Purpose
✅ What's Next?
Would you like me to explain Spring Boot REST APIs in detail? 🚀
6/6
Core Java Best Practices
2. Client-Server Architecture: The client and server are independent; the frontend and
backend can evolve separately.
4. Layered System: The API can have multiple layers (e.g., security, load balancing) without
the client being aware of them.
5. Uniform Interface: Uses standard HTTP methods (GET, POST, PUT, DELETE, PATCH).
📌 Example:
A REST API for a User Management System:
🔹 1/5
🔹 REST vs SOAP
REST (Representational State
Feature Transfer) SOAP (Simple Object Access Protocol)
Complexity Simple, uses standard HTTP More complex, requires more setup
methods
📌 REST is commonly used for modern web and mobile applications due to its simplicity
and performance advantages.
🔹 HTTP Methods
HTTP methods define actions performed on resources in a REST API.
HTTP
Method Description Example
GET Fetches data from the server GET /users (Get all users)
PUT Updates an existing resource (full update) PUT /users/1 (Update entire user)
PATCH Updates part of an existing resource (partial PATCH /users/1 (Update only a few
update) fields)
@RestController
@RequestMapping("/users")
public class UserController {
2/5
@GetMapping("/{id}")
public String getUser(@PathVariable Long id) {
return "Fetching user with ID " + id;
}
@PostMapping
public String createUser(@RequestBody String user) {
return "User created: " + user;
}
@PutMapping("/{id}")
public String updateUser(@PathVariable Long id, @RequestBody String user) {
return "User with ID " + id + " updated";
}
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
return "User with ID " + id + " deleted";
}
}
🔹 Status Codes
HTTP status codes indicate the result of an API request.
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
Optional<User> user = userRepository.findById(id);
return user.map(ResponseEntity::ok)
.orElseGet(() ->
ResponseEntity.status(HttpStatus.NOT_FOUND).build());
}
🔹 JSON vs XML
REST APIs typically use JSON (JavaScript Object Notation) as the data format, but they can
also support XML.
Data Types Supports numbers, strings, arrays, objects Treats everything as a string
{
"id": 1,
"name": "John Doe",
"email": "[email protected]"
}
<User>
<id>1</id>
4/5
<name>John Doe</name>
<email>[email protected]</email>
</User>
Spring Boot supports both JSON and XML using Jackson (default for JSON) and JAXB (for
XML).
✅ Summary
Concept Explanation
REST vs SOAP REST is lightweight and JSON-based; SOAP is XML-heavy and enterprise-focused
HTTP Methods GET , POST , PUT , PATCH , DELETE used to interact with APIs
JSON vs XML JSON is lightweight and widely used, while XML is used in older systems
🚀 What's Next?
Would you like me to explain Building REST APIs in Spring Boot with practical examples? 🎯
5/5
Core Java Best Practices
I'll provide an in-depth explanation of Creating a REST API in Spring Boot step by step.
2. Select:
Language: Java
java
@SpringBootApplication
public class RestApiApplication {
public static void main(String[] args) {
SpringApplication.run(RestApiApplication.class, args);
1/7
}
}
🔹 @RestController vs @Controller
Spring provides two annotations for handling web requests:
Annotation Purpose
📌 Example:
java
@Controller
public class ViewController {
@GetMapping("/home")
public String home() {
return "home"; // Returns a view (JSP/Thymeleaf)
}
}
@RestController
public class ApiController {
@GetMapping("/api/greet")
public String greet() {
return "Hello, REST API!"; // Returns JSON response
}
}
🔹 2/7
🔹 @RequestMapping, @GetMapping,
@PostMapping, @PutMapping,
@DeleteMapping
Spring Boot provides HTTP method-specific annotations:
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping
public String getAllUsers() {
return "Fetching all users";
}
@PostMapping
public String createUser() {
return "Creating a new user";
}
@PutMapping("/{id}")
public String updateUser(@PathVariable int id) {
return "Updating user with ID " + id;
}
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable int id) {
return "Deleting user with ID " + id;
3/7
}
}
@GetMapping("/{id}")
public String getUserById(@PathVariable int id) {
return "Fetching user with ID: " + id;
}
@GetMapping("/search")
public String searchUser(@RequestParam String name) {
return "Searching for user: " + name;
}
4/7
📌 Request: GET /users/search?name=John
📌 Response: "Searching for user: John"
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping
public String createUser(@RequestBody User user) {
return "User created: " + user.getName();
}
}
{
"id": 1,
"name": "Alice",
"email": "[email protected]"
}
5/7
2️⃣ Returning JSON Response with @ResponseBody
By default, @RestController returns JSON, but in @Controller , use @ResponseBody .
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable int id) {
return new User(id, "Alice", "[email protected]");
}
}
📌 Response (JSON):
json
{
"id": 1,
"name": "Alice",
"email": "[email protected]"
}
✅ Summary
Concept Explanation
Spring Boot Setup Use Spring Initializr to create a project with Spring Web dependency.
6/7
Concept Explanation
🚀 What's Next?
Would you like me to explain Exception Handling in Spring Boot REST APIs next? 🎯
7/7
Core Java Best Practices
I'll provide an in-depth explanation of Spring Boot Data JPA & Database Connectivity step
by step.
xml
<dependencies>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
1/9
2️⃣ Configure application.properties
For MySQL:
properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
For PostgreSQL:
properties
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
Interface Description
2/9
Interface Description
JpaRepository<T, ID> Extends CrudRepository , provides additional JPA features like pagination
and sorting.
import jakarta.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
}
3/9
3️⃣ Create a Service Layer
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
4/9
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@GetMapping("/{email}")
public User getUserByEmail(@PathVariable String email) {
return userService.getUserByEmail(email);
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.saveUser(user);
}
}
java
@Entity
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String bio;
5/9
@OneToOne
@JoinColumn(name = "user_id")
private User user;
}
java
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String product;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
java
@Entity
public class User {
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Order> orders;
}
6/9
java
@Entity
public class Employee {
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
}
java
@Entity
public class Student {
@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private List<Course> courses;
}
7/9
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Order> orders;
import org.springframework.data.jpa.repository.Query;
java
@NamedQuery(
name = "User.findByEmail",
query = "SELECT u FROM User u WHERE u.email = :email"
8/9
)
@Entity
public class User { ... }
Use in UserRepository :
java
✅ Summary
Concept Explanation
🚀 What's Next?
Would you like me to explain Spring Boot Exception Handling in REST APIs next? 🎯
9/9
Core Java Best Practices
🚀 Exception Handling in REST APIs (Spring Boot)
Exception handling in a Spring Boot REST API ensures that errors are properly handled and
informative responses are returned to clients.
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
try {
User user = userService.getUserById(id);
return ResponseEntity.ok(user);
} catch (UserNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
}
1/6
2️⃣ Handling Exceptions with
@ExceptionHandler
The @ExceptionHandler annotation catches specific exceptions inside a single controller.
java
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id); // Throws UserNotFoundException
}
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleUserNotFoundException(UserNotFoundException
e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
}
}
2/6
📌 Steps to Create Global Exception Handling
1️⃣ Create a Custom Exception ( UserNotFoundException )
java
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@ExceptionHandler(UserNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleUserNotFoundException(UserNotFoundException e) {
return e.getMessage();
}
4️⃣ 3/6
4️⃣ Custom Exceptions using
ResponseStatusException
Spring Boot provides ResponseStatusException to return HTTP errors directly inside the
service layer.
java
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;
java
4/6
public ErrorResponse(String message, int status) {
this.message = message;
this.status = status;
}
java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse>
handleUserNotFoundException(UserNotFoundException e) {
ErrorResponse errorResponse = new ErrorResponse(e.getMessage(),
HttpStatus.NOT_FOUND.value());
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(Exception e) {
ErrorResponse errorResponse = new ErrorResponse("Something went wrong",
HttpStatus.INTERNAL_SERVER_ERROR.value());
return new ResponseEntity<>(errorResponse,
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
{
"message": "User not found",
"status": 404
}
🔹 5/6
🔹 Summary
Approach Description Scope
ResponseStatusException Throws HTTP errors directly from service layer Service Layer
🚀 Next Steps
Would you like me to explain Spring Boot Logging & Monitoring (with SLF4J, Logback, and
Actuator)? 📊
6/6
Core Java Best Practices
🔹 Topics Covered
✅ Validating Request Body ( @Valid , @NotNull , @Size , etc.)
✅ Custom Validators
✅ Handling Validation Errors ( BindingResult )
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2️⃣ 1/7
2️⃣ Validating Request Body Using
@Valid
We use @Valid along with Jakarta Validation annotations in DTOs.
java
import jakarta.validation.constraints.*;
2/7
Now, let's create a REST API to validate UserDTO .
java
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping("/create")
public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO user) {
return ResponseEntity.ok("User created successfully!");
}
}
✅ What Happens?
If the request body is valid, the API returns "User created successfully!"
If the request body fails validation, Spring Boot automatically returns an error
response.
4️⃣
(
Handling Validation Errors
BindingResult)
By default, Spring Boot returns a generic error message if validation fails.
We can customize this using BindingResult .
java
@PostMapping("/create")
public ResponseEntity<?> createUser(@Valid @RequestBody UserDTO user, BindingResult
3/7
result) {
if (result.hasErrors()) {
String errors = result.getAllErrors().stream()
.map(error -> error.getDefaultMessage())
.reduce("", (a, b) -> a + ", " + b);
return ResponseEntity.badRequest().body(errors);
}
return ResponseEntity.ok("User created successfully!");
}
{
"name": "Jo",
"email": "invalid-email",
"age": 16
}
📌 Response:
json
{
"errors": "Name must be at least 3 characters, Invalid email format, Age must be
at least 18"
}
4/7
java
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>>
handleValidationErrors(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage()));
{
"name": "Name must be at least 3 characters",
"email": "Invalid email format",
"age": "Age must be at least 18"
}
5/7
📌 Example: Creating a Custom Age Validator
1️⃣ Create a Custom Annotation
java
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = AgeValidator.class)
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidAge {
String message() default "Age must be between 18 and 60";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
@ValidAge
private int age;
6/7
// Other fields, getters, and setters
}
📌 Now, if age is not between 18 and 60, the API will return:
json
{
"age": "Age must be between 18 and 60"
}
🔹 Summary
Feature Description
🚀 Next Steps
Would you like me to explain Spring Boot Logging & Monitoring (SLF4J, Logback,
Actuator)? 📊
7/7
Core Java Best Practices
🔹 Topics Covered
✅ Securing REST APIs with Spring Security
✅ JWT (JSON Web Token) Authentication
✅ OAuth2 Authorization
✅ Role-Based Access Control (RBAC)
xml
<dependency>
<groupId>org.springframework.boot</groupId>
1/9
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.11.5</version>
</dependency>
3. The client stores the token (e.g., in localStorage) and includes it in every API request.
java
2/9
import org.springframework.security.core.userdetails.*;
import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class JwtUtil {
private String secretKey = "mySecret";
3/9
}
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/auth")
public class AuthController {
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String
password) {
4/9
if ("admin".equals(username) && "password".equals(password)) {
return jwtUtil.generateToken(username);
}
return "Invalid Credentials";
}
}
POST /auth/login
{
"username": "admin",
"password": "password"
}
📌 Response:
json
{
"token": "eyJhbGciOiJIUzI1NiIs..."
}
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.*;
import javax.servlet.http.*;
5/9
public JwtFilter(JwtUtil jwtUtil, CustomUserDetailsService userDetailsService) {
this.jwtUtil = jwtUtil;
this.userDetailsService = userDetailsService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
response, FilterChain chain)
throws ServletException, IOException {
String token = request.getHeader("Authorization");
if (jwtUtil.validateToken(token, username)) {
SecurityContextHolder.getContext().setAuthentication(new
UsernamePasswordAuthenticationToken(userDetails, null,
userDetails.getAuthorities()));
}
}
chain.doFilter(request, response);
}
}
import org.springframework.context.annotation.*;
import
org.springframework.security.config.annotation.authentication.configuration.Authenticat
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
6/9
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws
Exception {
http.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/auth/login").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
return http.build();
}
}
✅ Only allows login API without authentication. Other APIs require a JWT token.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
yaml
spring:
security:
oauth2:
client:
registration:
google:
client-id: your-client-id
client-secret: your-client-secret
scope: profile, email
import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class OAuth2SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws
Exception {
http.oauth2Login();
return http.build();
}
}
8/9
📌 Secure APIs Based on Roles
java
.authorizeHttpRequests()
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
✅ Users with ROLE_ADMIN can access /admin/** APIs, while ROLE_USER and ROLE_ADMIN
can access /user/** APIs.
🔹 Summary
Feature Description
🚀 Next Steps
Would you like me to explain Logging & Monitoring in Spring Boot (SLF4J, Logback,
Actuator)? 📊
9/9
Core Java Best Practices
🔹 Topics Covered
✅ Logging with SLF4J and Logback
✅ Using Spring Boot Actuator for Monitoring
✅ Exposing Health & Metrics Endpoints
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
1/6
📌 Using SLF4J in Java Classes
java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/logging")
public class LoggingController {
@GetMapping("/test")
public String logTest() {
logger.info("INFO: This is an info message");
logger.debug("DEBUG: Debugging details");
logger.warn("WARN: Warning message");
logger.error("ERROR: Something went wrong!");
return "Logging Example in Spring Boot";
}
}
Located in src/main/resources/
xml
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} -
%msg%n</pattern>
2/6
</encoder>
</appender>
properties
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.file.name=logs/app.log
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} -
%msg%n
Metrics ( /actuator/metrics )
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
properties
4/6
Run the app and visit:
📌 http://localhost:8080/actuator/health
json
{
"status": "UP"
}
📌 Example:
📌 http://localhost:8080/actuator/metrics/jvm.memory.used
json
{
"name": "jvm.memory.used",
"measurements": [{"statistic": "VALUE", "value": 50914560}]
}
json
{
"configuredLevel": "DEBUG",
5/6
"effectiveLevel": "DEBUG"
}
🔹 Summary
Feature Description
SLF4J & Logback Logs events with different log levels (INFO, DEBUG, ERROR)
Dynamic Log Level Changes Modify log levels at runtime via Actuator
🚀 Next Steps
Would you like to explore Spring Boot Caching (EhCache, Redis) for performance
optimization? 🚀
6/6
Core Java Best Practices
🔹 Topics Covered
✅ Enabling Caching ( @EnableCaching )
✅ Using Redis Cache
✅ Cache Eviction Strategies
📌 What is Caching?
Caching stores frequently used data in memory (RAM) to improve performance by avoiding
repeated database queries.
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
1/6
✅ Spring Boot supports multiple caching providers like EhCache, Redis, Caffeine, etc.
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class CacheApplication {
public static void main(String[] args) {
SpringApplication.run(CacheApplication.class, args);
}
}
java
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
2/6
}
}
✅ First-time execution fetches data from the database. Next time, it retrieves from the
cache.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
properties
spring.redis.host=localhost
spring.redis.port=6379
3/6
📌 Creating Redis Cache Configuration
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory());
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
return template;
}
}
java
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
4/6
@Service
public class ProductService {
📌 Using @CacheEvict
java
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
📌 Using @CachePut
5/6
If you want to update cache when updating data, use @CachePut .
java
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
🔹 Summary
Feature Description
🚀 Next Steps
Would you like to explore Spring Boot Email Sending (SMTP, JavaMailSender)? 📧
6/6
Core Java Best Practices
🔹 Topics Covered
✅ Unit Testing with JUnit & Mockito
✅ Integration Testing with MockMvc
✅ Testing REST APIs with Postman
📌 Tools Used:
✅ JUnit 5 - Java Testing Framework
✅ Mockito - Mock Objects for Unit Testing
xml
1/7
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
✅ Product Entity
java
import org.springframework.data.jpa.repository.JpaRepository;
2/7
✅ Product Service
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Optional;
@ExtendWith(MockitoExtension.class)
3/7
public class ProductServiceTest {
@Mock
private ProductRepository productRepository;
@InjectMocks
private ProductService productService;
@Test
public void testGetProductById() {
Product product = new Product(1L, "Laptop", 75000);
when(productRepository.findById(1L)).thenReturn(Optional.of(product));
assertEquals("Laptop", result.getName());
assertEquals(75000, result.getPrice());
}
}
📌 Tools Used:
✅ MockMvc - Mocks HTTP requests
✅ Spring Boot Test - Test Spring Boot components
4/7
(Spring Boot already includes this in spring-boot-starter-test ).
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
return productService.getProductById(id);
}
}
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
5/7
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
@WebMvcTest(ProductController.class)
public class ProductControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testGetProductById() throws Exception {
mockMvc.perform(get("/products/1"))
.andExpect(status().isOk());
}
}
json
{
"id": 1,
"name": "Laptop",
"price": 75000
}
6/7
✅ If the response matches expected output, the API works correctly.
🔹 Summary
Testing Type Tools Used Purpose
🚀 Next Steps
Would you like a detailed guide on Spring Boot Email Sending (SMTP, JavaMailSender)? 📧
7/7
Core Java Best Practices
🔹 Topics Covered
✅ What is Swagger (OpenAPI)?
✅ Setting up Swagger with springdoc-openapi
✅ Customizing API Documentation
OpenAPI is the standard for defining APIs, and Swagger is one of its implementations.
xml
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.1.0</version>
</dependency>
📌 Access Swagger UI
Once the application is running, open Swagger UI in your browser:
📌 URL: http://localhost:8080/swagger-ui.html
You will see an interactive API documentation UI where you can test API endpoints directly.
java
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Arrays;
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping
public List<String> getAllProducts() {
return Arrays.asList("Laptop", "Smartphone", "Tablet");
2/5
}
@GetMapping("/{id}")
public String getProductById(@PathVariable int id) {
List<String> products = Arrays.asList("Laptop", "Smartphone", "Tablet");
return products.get(id);
}
}
java
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Arrays;
@RestController
@RequestMapping("/products")
public class ProductController {
3/5
public List<String> getAllProducts() {
return Arrays.asList("Laptop", "Smartphone", "Tablet");
}
java
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
4/5
.info(new Info()
.title("Product API")
.version("1.0")
.description("API documentation for managing products"));
}
}
🔹 Summary
Feature Swagger Integration
🚀 Next Steps
Would you like a detailed guide on Spring Boot Deployment (Docker, Kubernetes, AWS,
Heroku)? 🚀
5/5
Core Java Best Practices
🔹 Topics Covered
✅ Building a Spring Boot JAR/WAR
✅ Deploying to Docker & Kubernetes
✅ Deploying on AWS (EC2, S3, RDS)
✅ Running Spring Boot with Apache Tomcat
xml
<packaging>jar</packaging>
sh
1/6
3. Find the JAR file in the target/ folder:
bash
target/myapp-0.0.1-SNAPSHOT.jar
sh
dockerfile
FROM openjdk:17
COPY target/myapp-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
sh
sh
2/6
📌 Deploying to Kubernetes
1. Create a Kubernetes deployment YAML file ( deployment.yaml ):
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-spring-boot-app
spec:
replicas: 2
selector:
matchLabels:
app: my-spring-boot-app
template:
metadata:
labels:
app: my-spring-boot-app
spec:
containers:
- name: my-spring-boot-app
image: my-docker-hub-username/my-spring-boot-app:latest
ports:
- containerPort: 8080
sh
3/6
2. Connect to EC2 via SSH:
sh
sh
sh
sh
properties
spring.datasource.url=jdbc:mysql://your-rds-endpoint:3306/dbname
spring.datasource.username=your-db-username
spring.datasource.password=your-db-password
4/6
✅ Now your Spring Boot app is connected to AWS RDS!
xml
<packaging>war</packaging>
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import
org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class MyApp extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
sh
5/6
mvn clean package
sh
cp target/myapp-0.0.1-SNAPSHOT.war /opt/tomcat/webapps/
bash
http://your-server-ip:8080/myapp
🔹 Summary
Deployment Method Steps
🚀 Next Steps
Would you like a detailed guide on CI/CD (GitHub Actions, Jenkins, AWS CodeDeploy)? 🚀
6/6
Core Java Best Practices
Example:
java
@Controller
public class MyController {
@GetMapping("/home")
public String home() {
return "index"; // Returns "index.html"
}
}
@RestController
Example:
java
@RestController
public class MyRestController {
@GetMapping("/hello")
public String sayHello() {
return "Hello, World!";
}
}
1/8
✅ Use @RestController for REST APIs and @Controller for web pages.
java
@Component
public class MyComponent {
public String getMessage() {
return "Hello from Component!";
}
}
java
@Service
public class UserService {
public String getUser() {
return "User fetched!";
}
}
java
2/8
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
Example:
java
@RestController
public class UserController {
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
if (id < 1) {
throw new IllegalArgumentException("Invalid ID");
}
return new User(id, "John Doe");
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<String> handleException(IllegalArgumentException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
}
3/8
Example:
java
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGlobalException(Exception ex) {
return new ResponseEntity<>("Error: " + ex.getMessage(),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
4️⃣
JWT?
How do you secure a REST API using
3. User includes the JWT token in the request header for every API call.
xml
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.11.5</version>
</dependency>
4/8
Step 2: Create JWT Utility Class
java
import io.jsonwebtoken.*;
import java.util.Date;
@Component
public class JwtUtil {
private String secretKey = "mySecret";
java
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.web.filter.OncePerRequestFilter;
@Component
5/8
public class JwtFilter extends OncePerRequestFilter {
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
response, FilterChain chain)
throws ServletException, IOException {
String token = request.getHeader("Authorization");
Enable Caching Use @EnableCaching and Redis for repeated API calls
Use a Load Balancer Distribute API traffic with Nginx or AWS ELB
6/8
@EnableCaching
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@Async
public void processHeavyTask() {
System.out.println("Processing in background...");
}
}
🔹 Summary of Answers
Question Key Answer
7/8
Question Key Answer
4. How to secure a REST API using JWT? Generate JWT token, validate it in a filter, and secure API
requests.
5. How to improve API performance? Use caching, async processing, database optimization,
and load balancing.
🚀 Would you like a hands-on project implementing these concepts? Let me know! 😊
8/8