Last active
May 21, 2020 10:19
-
-
Save Miczeq22/79ee1b82c20f75c65c7cf216f30815ec to your computer and use it in GitHub Desktop.
CQRS Article
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| abstract class CommandHandler<T extends Command<unknown>> { | |
| constructor(public readonly type: string) {} | |
| public abstract async execute(command: T); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| abstract class Command<T> { | |
| constructor(public readonly type: string, public readonly payload: T) {} | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const registerCustomerAction = ( | |
| payload: RegisterCustomerPayload, | |
| context: ApplicationContext | |
| ) => context.commandBus.execute(new RegisterCustomerCommand(payload)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function getOrCreateProduct(data: ProductData) { | |
| let existingProduct = productRepository.findByAttributes(data); | |
| if (!existingProduct) { | |
| existingProduct = productRepository.save(data); | |
| } | |
| return existingProduct; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export const resolvers = { | |
| Mutation: { | |
| addCardToDeck, | |
| removeCardFromDeck, | |
| }, | |
| Query: { | |
| getCardsForDeck, | |
| }, | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| : '', | |
| })), | |
| ); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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