SpringBoot Chapter 2 : Layered Architecture Design Pattern in SpringBoot
- β What is Layered Architecture?
- π Why should we NOT Combine Service & Repository?
- π Request Lifecycle
- β Summary
β What is Layered Architecture?
Layered Architecture (also called n-tier architecture) is a software design pattern that organizes an application into logical layers β each with a specific responsibility.
Common layers in this architecture
| Layer | Description |
|---|---|
| Controller | Handles HTTP requests and returns responses |
| Service | Contains business rules / app logic |
| Repository | Talks to the database (CRUD operations) |
| Model (Entity) | Defines data structure (Java classes mapped to DB tables) |
| Security (optional) | Manages login, roles, authentication |
| Utils/Helper (optional) | Common functionality like converters, validators |
Letβs consider package structure of a todo-application built using layered architecture approach:
com.example.todoapp
β
βββ /controller
β βββ TodoController.java
β βββ AuthController.java
β
βββ /service
β βββ TodoService.java
β βββ UserService.java
β
βββ /repository
β βββ TodoRepository.java
β βββ UserRepository.java
β
βββ /model
β βββ Todo.java
β βββ User.java
β
βββ /security
β βββ JwtFilter.java
β βββ SecurityConfig.java
β
βββ /utils
β βββ Validator.java
β
βββ TodoApplication.java
The benefits of using layered architecture approach areβ¦
| Benefit | Description |
|---|---|
| π Readability | We can quickly locate code based on its function |
| π Reusability | Services & repositories can be reused in multiple controllers |
| π§ͺ Testability | We can test each layer in isolation (e.g., mock service in controller tests) |
| π§Ό Maintainability | Makes it easier to refactor or scale features |
π§± What Each Layer Does
1. Controller Layer (controller)
Talks to the outside world β handles HTTP requests and responses.
- Maps routes like
/api/todos - Accepts user input (usually in DTO form)
- Sends it to the Service layer
- Returns the result to the client
@RestController
@RequestMapping("/api/todos")
public class TodoController {
@Autowired
private TodoService todoService;
@GetMapping
public List<Todo> getTodos() {
return todoService.getAllTodos();
}
}
2. Service Layer (service)
Contains business logic β rules for how the app behaves.
- Orchestrates data between controller and repository
- Contains logic like filtering tasks by user, validating input, or sorting
- Keeps controllers thin and focused
@Service
public class TodoService {
@Autowired
private TodoRepository todoRepository;
public List<Todo> getAllTodos() {
return todoRepository.findAll();
}
}
3. Repository Layer (repository)
Talks directly to the database (or in-memory data source).
- Interface that extends
JpaRepositoryorCrudRepository - Automatically gives we methods like
findAll(),save(),deleteById() - Uses Spring Data JPA to reduce boilerplate
public interface TodoRepository extends JpaRepository<Todo, Long> {
List<Todo> findByUserId(Long userId);
}
4. Model Layer (model)
Defines the data structure (aka Entity).
@Entityclasses likeTodo,User- Maps to tables in the database
- Has annotations like
@Id,@Column,@ManyToOne
5. Security Layer (security)
Handles authentication and authorization
- JWT token filters
- Custom
UserDetailsService - Spring Security configuration class
6. Application Entry Point
@SpringBootApplication
public class TodoAppApplication {
public static void main(String[] args) {
SpringApplication.run(TodoAppApplication.class, args);
}
}
- Boots the Spring context
- Scans components (
@ComponentScan) to wire everything together
π Why should we NOT Combine Service & Repository?
We can technically skip the service layer and call the repository from the controller in small prototypes, but hereβs why thatβs discouraged in real-world apps:
| Without Service | With Service |
|---|---|
| Controller gets bloated | Controller is clean |
| Business logic is scattered | Logic is centralized |
| Hard to test in isolation | Easier to mock in unit tests |
| Tight coupling | Loose coupling |
So, Service Layer = Flexibility + Clean Code + Better Design
π Request Lifecycle
Client ->> Controller: GET /api/todos
Controller ->> Service: getAllTodos()
Service ->> Repository: findAll()
Repository -->> Service: List<Todo>
Service -->> Controller: List<Todo>
Controller -->> Client: 200 OK (JSON)
β Summary
| Layer | Responsibility | Why Itβs Needed |
|---|---|---|
| Controller | Handles HTTP requests/responses | Keeps web concerns separate |
| Service | Business logic & orchestration | Clean, reusable logic layer |
| Repository | DB operations using Spring Data JPA | Minimal boilerplate for data access |
| Model | Defines database schema (Entity classes) | Maps Java to DB tables |
| Security | Auth with JWT / Spring Security | Adds protected access |
| App class | Bootstraps the app | Starts the Spring context |