Interview frequency: …
Short answer
Divide the system into concentric layers: Entities, Use Cases, Controllers/Presenters, and Infrastructure, with dependencies always pointing inward toward abstract business logic.
Explanation
The goal is to make core business logic (Domain & Use Cases) entirely independent of technical details such as the framework (Express/Fastify) or database type (PostgreSQL/MongoDB). Dependency Inversion achieves this: the Use Cases layer defines interfaces (Interfaces/Ports), and the Infrastructure layer implements and provides them through Dependency Injection.
Code example
// Use Case Independent of the database
export class RegisterUserUseCase {
constructor(private readonly userRepo: UserRepositoryPort) {}
async execute(dto: RegisterUserDto) {
// Pure business logic
}
}Common mistakes
- Importing database models (such as Mongoose or TypeORM models) directly into the Use Cases layer.