.
└── src
├── app → Application services layer
│ └── usecase → Application business rules
├── domain → Enterprise core business layer such as domain model objects (Aggregates, Entities, Value Objects) and repository interfaces
└── infra → Frameworks, drivers and tools such as Database, the Web Framework, mailing/logging/glue code etc.
├── config → Application configuration files, modules and services
├── data → Database ORMs middleware
├── entrypoint → Main application entry point
│ └── web
│ └── controller
└── repositories → Implementation of domain repository interfaces
src
: This is a project directory one level up from the root directory. It hold all necessary folders and files that make clean architecture.
-
domain
: It's core/domain layer. It does not depends on any layer as outer layer rather depends on it. It holds all the core entities of the domain. For example: If a domain has User as a core component, that User becomes the part of domain layer. -
app
: It's an application layer. It consists of:usecase
: It's an interactor layer. It also acts as a service component which interacts with the domain layer. It injects repositories and implements certain boundry|port, in other words an interface.
-
infra
: It's an infrastructure layer. It is also the outermost layer which may have server components as follows:config
: Holds configuration of entier layer and the project itself.data
: The database could be any of your choice. Holds database schemas.repository
: Repository is a place/file (or a class that implements certain boundry|port) which mainly has CRUD operations implementation (for rg: createUser, deleteUser) and gets injected in particular usecases. Also, it could be for each type of database. For example: UserRepositoryMongoDb, UserRepositoryMysql, etc. This way usecase/service layer will be intact and does not need to get updated per database type, just inject UserRepositoryMongoDb or UserRepositoryMysql.framework
: any framework of your choice. For example: expressentrypoint
: It's a presentation layer. It is also the outermost layer which may have several components as follows:web/controller
: That receives HTTP req and then send back approriate response. It implements Input Port or an Interface (for example: IUserInputDto) that governs the incoming values, and communicates with the presenter. Controller injects the usecases as per need.presenter
: A component that pass the response to the UI. It implements Output Port or an Interface (for example: IUserOutoutDto) that governs the outgoing values (DTO), and presents to the UI.gateway
: This could be an API Gateway.
ui
: This could be a view of the application. For example: a console prompt, web UI.
Both Input & Output Ports are called Boundry or Interface to govern the incoming/outgoing data or make mandatory to implement any function/method/properties that must be implemented. They're implemented by the usecases and repositories. It's a good practice to add a definition folder under each layer so that you could define types, interface or base-class.