UNPKG

@hexadrop/command

Version:

Hexagonal architecture utils library

135 lines (99 loc) 4.14 kB
<h1 align="center"> @hexadrop/command </h1> <p align="center"> Opinionated package to create and dispatch commands for CQRS applications. </p> ```bash npm install --save @hexadrop/command ``` **Using bun** ```bash bun add @hexadrop/command ``` ## What it does This package is an opinionated utility designed to streamline the creation and dispatching commands in CQRS (Command Query Responsibility Segregation) applications. It provides a set of abstractions and utilities that allow developers to handle commands in a structured and efficient way. Key features include: - **Command Creation**: Simplifies the process of creating new commands. - **Command Dispatching**: Provides mechanisms to dispatch commands to their respective handlers. - **Command Handler Decorators**: Provides decorators to define command handlers. ## How to use First of all define your commands. A command is a simple class that extends the `Command` class and defines the properties that will be passed to the command handler. ```typescript // src/commands/create-user.command.ts class CreateUserCommand extends Command { static override COMMAND_NAME = 'user.create'; constructor( readonly id: string, readonly name: string, readonly age: number ) { super(CreateUserCommand.COMMAND_NAME); } } ``` ```typescript // src/commands/delete-user.command.ts class DeleteUserCommand extends Command { static override COMMAND_NAME = 'user.delete'; constructor(readonly id: string) { super(CreateUserCommand.COMMAND_NAME); } } ``` Then define your command handlers. A command handler is a simple class that implements the `CommandHandler` interface ```typescript // src/handlers/create-user.handler.ts import Either from '@hexadrop/either'; class CreateUserHandler implements CommandHandler<CreateUserCommand> { constructor(private readonly usersRepository: UsersRepository) {} async handle(command: CreateUserCommand): Promise<Either<DomainError, void>> { const { age, id, name } = command; await this.usersRepository.create({ age, id, name }); return Either.right(); } } ``` ```typescript // src/handlers/delete-user.handler.ts import Either from '@hexadrop/either'; class DeleteUserHandler implements CommandHandler<DeleteUserCommand> { constructor(private readonly usersRepository: UsersRepository) {} async handle(command: DeleteUserCommand): Promise<Either<DomainError, void>> { const { id } = command; await this.usersRepository.delete(id); return Either.right(); } } ``` Finally, you can dispatch your commands. To do so you need to create a `CommandBus` instance and register your command handlers. ```typescript // src/index.ts import CommandBus from '@hexadrop/command/bus'; import SyncCommandBus from '@hexadrop/command/bus/sync'; import InMemoryCommandHandlers from '@hexadrop/command/handlers/memory'; import { CreateUserCommand, DeleteUserCommand } from './commands'; import { CreateUserHandler, DeleteUserHandler } from './handlers'; const usersRepository; // Your users repository const createUserHandler = new CreateUserHandler(usersRepository); const deleteUserHandler = new DeleteUserHandler(usersRepository); const handlers = new InMemoryCommandHandlers(); handlers.register(CreateUserCommand, createUserHandler); handlers.register(DeleteUserCommand, deleteUserHandler); const commandBus: CommandBus = new SyncCommandBus(handlers); commandBus.dispatch(new CreateUserCommand('1', 'John', 30)); commandBus.dispatch(new DeleteUserCommand('1')); ``` ## Hexadrop Code Quality Standards Publishing this package we are committing ourselves to the following code quality standards: - Respect **Semantic Versioning**: No breaking changes in patch or minor versions - No surprises in transitive dependencies: Use the **bare minimum dependencies** needed to meet the purpose - **One specific purpose** to meet without having to carry a bunch of unnecessary other utilities - **Tests** as documentation and usage examples - **Well documented README** showing how to install and use - **License favoring Open Source** and collaboration