-
Notifications
You must be signed in to change notification settings - Fork 23
Open
Labels
questionFurther information is requestedFurther information is requested
Description
Summary
I'm studying this template to understand the architectural patterns and noticed different approaches for invoking Use Cases between the Auth and User modules. Could you help explain the reasoning behind these design choices?
Observed Patterns
Auth Module Pattern
// AuthController calls UseCase directly
@Post('/login')
async login(@Body() body: LoginBody): Promise<JwtUser> {
return this.jwtAuth.generateJwtUser(
getOrThrowWith(
await this.loginUseCase.execute(body), // ← Direct UseCase call
() => new UnauthorizedException('Login Error!'),
),
);
}
User Module Pattern
// UserController uses CQRS Command → Handler → UseCase
@Post()
async createUser(@Body() body: CreateUserBody) {
getOrThrowWith(
await this.commandBus.execute(
this.getCommandForRole(body, UserRole.USER), // ← CQRS Command
),
() => new BadRequestException('Error in User Creation'),
);
}
// Then CreateUserHandler calls the UseCase
@CommandHandler(CreateUserCommand)
export class CreateUserHandler implements ICommandHandler<CreateUserCommand> {
async execute(command: CreateUserCommand): Promise<Option<User>> {
return await this.createUserUseCase.execute({
// command properties...
});
}
}
Questions
- What are the design principles behind choosing
Controller → UseCase → CommandvsController → Command → UseCase? - Are there specific scenarios or requirements where one pattern is preferred over the other?
- For the cross-module communication (
Auth'sSignupUseCasedispatchingRegisterUserCommandhandled inUsermodule), isn't this an obstacle to moving to a microservice architecture with minimal effort?
Thank you for creating such a comprehensive template with excellent DevOps practices!
Metadata
Metadata
Assignees
Labels
questionFurther information is requestedFurther information is requested