Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
CQRS Article
abstract class CommandHandler<T extends Command<unknown>> {
constructor(public readonly type: string) {}
public abstract async execute(command: T);
}
abstract class Command<T> {
constructor(public readonly type: string, public readonly payload: T) {}
}
class CommandBus {
constructor(private readonly handlers: CommandHandler<any>[]) {}
public async execute(command: Command<unknown>) {
const handler = this.handlers.find(
(existingHandler) => existingHandler.type === command.type
);
if (!handler) {
throw new Error(`Handler for command: ${command.type} does not exist.`);
}
return handler.execute(command);
}
}
const registerCustomerAction = (
payload: RegisterCustomerPayload,
context: ApplicationContext
) => context.commandBus.execute(new RegisterCustomerCommand(payload));
function getOrCreateProduct(data: ProductData) {
let existingProduct = productRepository.findByAttributes(data);
if (!existingProduct) {
existingProduct = productRepository.save(data);
}
return existingProduct;
}
export const resolvers = {
Mutation: {
addCardToDeck,
removeCardFromDeck,
},
Query: {
getCardsForDeck,
},
};
interface GetUserEnrolledDecksQueryHandlerDependencies {
enrolledDeckRepository: EnrolledDeckRepository;
deckElasticView: ElasticView<Deck>;
storageClient: StorageClient;
}
export class GetUserEnrolledDecksQueryHandler extends QueryHandler<
GetUserEnrolledDecks,
GetUserEnrolledDecksQueryResult
> {
constructor(
private readonly dependencies: GetUserEnrolledDecksQueryHandlerDependencies,
) {
super(GET_USER_ENROLLED_DECKS_QUERY_TYPE);
}
public async execute({ payload: { userId } }: GetUserEnrolledDecks) {
const {
enrolledDeckRepository,
deckElasticView,
storageClient,
} = this.dependencies;
const enrolledDecks = await enrolledDeckRepository.getAllByUser(userId);
const { items } = await deckElasticView.findMany({
ids: enrolledDecks.map(enrolledDeck => enrolledDeck.getDeckId()),
});
return new GetUserEnrolledDecksQueryResult(
items.map(item => ({
...item,
imgUrl: item.imgUrl
? storageClient.getPublicUrlResolver(item.imgUrl)
: '',
})),
);
}
}
interface Dependencies {
customerRepository: CustomerRepository;
}
class RegisterCustomerCommandHandler extends CommandHandler<
RegisterCustomerCommand
> {
constructor(private readonly dependencies: Dependencies) {
super(REGISTER_CUSTOMER_COMMAND_TYPE);
}
public async execute({ payload }: RegisterCustomerCommand) {
const { customerRepository } = this.dependencies;
const { email } = payload;
const existingUser = await customerRepository.findByEmail(email);
if (existingUser) {
throw new Error(`User with email: "${email}" already exist.`);
}
await customerRepository.insert(payload);
}
}
interface RegisterCustomerPayload {
email: string;
password: string;
name: string;
}
export const REGISTER_CUSTOMER_COMMAND_TYPE = "customer/register";
class RegisterCustomerCommand extends Command<
RegisterCustomerPayload
> {
constructor(payload: RegisterCustomerPayload) {
super(REGISTER_CUSTOMER_COMMAND_TYPE, payload);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment