Skip to content

Lucas-E/Spring-boot-clean-architecture

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spring Boot Clean Architecture

💡 Motivation

This repository provides a practical implementation of the principles of Clean Architecture in a Spring Boot project. While Clean Architecture offers well-defined guidelines for separation of concerns and independence of frameworks, it often leaves the details of implementation to the developer.

The goal here is to serve as a clear and organized reference for structuring a scalable and maintainable backend application following Clean Architecture concepts, adapted to the Spring ecosystem.


🏗️ Project Structure & Motivation

The project is structured into distinct layers, each with a specific responsibility, allowing for low coupling, high cohesion, and easy testability:

1. application/

Contains use cases — application-specific business rules.

2. domain/

The core of the application, containing:

  • Domain entities
  • Repository interfaces
  • Gateway contracts

Completely independent of frameworks.

3. infrastructure/

Framework-dependent layer:

  • Implementations of persistence (e.g., MongoDB)
  • Spring configurations (CORS, Security)
  • Controllers and DTOs
  • Exception handling

4. resources/

Standard Spring Boot config files (application.properties, etc.).


🔄 Dependency Flow

This ensures business logic is pure and testable, with all framework dependencies pushed to the outermost layer.


🧱 Layers Breakdown (with User Module Example)

Clean Architecture divides the system into concentric layers, separating business rules from implementation details. Each layer has a specific and intentional responsibility.


🔹 1. domain/

Responsibility: Represents the core of the system, containing only business rules and entities. This layer is completely independent of frameworks and technologies.

Why?

  • Keeps business logic pure and isolated from infrastructure concerns.
  • Makes the system easier to test and evolve.

In the user module:

  • User.java: Domain entity representing a user with fields and behaviors.
  • IUserRepository.java: An interface (contract) for user persistence. It doesn’t know how or where the data is stored.
  • UserGateway.java: Optional gateway for external integrations (e.g., messaging, APIs) related to users.

🔹 2. application/usecase/

Responsibility: Orchestrates use cases of the system. It calls gateways and repositories to execute business flows.

Why?

  • Separates the "what" (business actions) from the "how" (infrastructure).
  • Keeps use case logic isolated from delivery and persistence.

In the user module:

  • CreateUserUseCase.java: Receives user input and triggers logic to create a user.
  • Calls UserGateway or IUserRepository as needed.

🔹 3. infrastructure/

Responsibility: Contains implementations of interfaces from the domain layer. This includes frameworks, databases, APIs, messaging, etc.

Why?

  • Keeps external systems and tools encapsulated.
  • Allows changing tech (e.g., from MongoDB to PostgreSQL) without touching the core logic.

In the user module:

  • UserRepositoryImpl.java: Implements IUserRepository, uses Spring Data or raw queries.
  • UserGatewayImpl.java: Implements UserGateway, interacts with external services.

🔹 4. infrastructure/config/

Responsibility: Defines configurations like dependency injection, security, exception handling, etc.

Why?

  • Keeps framework-related logic centralized.
  • Decouples setup logic from business code.

🔹 5. infrastructure/controller/ (or web/, adapter/controller/)

Responsibility: Handles HTTP requests/responses and maps them to use cases.

Why?

  • Keeps delivery logic (e.g., REST, GraphQL) separate from business logic.
  • Makes it easy to swap interfaces (e.g., REST → gRPC) without affecting use cases.

In the user module:

  • UserController.java: Exposes endpoints like POST /users, maps request body to DTO, and calls CreateUserUseCase.

🔹 6. infrastructure/controller/dtos/

Responsibility: Defines request/response objects for API communication.

Why?

  • Protects domain models from leaking to the external world.
  • Allows input validation with annotations (e.g., @NotNull, @Email).

In the user module:

  • CreateUserDto.java: Contains fields like firstName, email, and conversion methods to domain model (toDomain()).

📌 Why Clean Architecture?

  • Keeps business logic framework-agnostic
  • Promotes testability and scalability
  • Encourages separation of concerns
  • Facilitates maintenance and evolution

About

Repository as an example of clean architecture with Spring Boot, Spring Data MongoDB and Spring Security

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages