The Readmodel is a prepared view on data that is projected from Events. The data schema of a Readmodel is optimized for the need of the consumer that queries the Readmodel.
Determines the amount of entities returned by the query:
The Name is used to name the Query and Query Handler. It also sets the folder and infrastructure name for the Usecase.
For more details, see Naming.
Your screen should look like that
A Query is a Data Transfer Object (DTO) that contains the information needed to fetch data from the system. It acts as a request for data retrieval and is passed to the QueryHandler.
A Query can be found at: Task/src/useCases/read/TaskOverview/application/GetTasksByAssigneeIdQuery.ts
.
1import { isType } from "is-what";2import { validate } from "uuid";3import { OverwriteProtectionBody, ValidationError } from "@codebricks/typebricks";45export interface GetTasksByAssigneeIdQueryProperties {6 assigneeId: string;7}89export class GetTasksByAssigneeIdQuery {10 constructor(readonly properties: GetTasksByAssigneeIdQueryProperties) {11 this.validate();12 }1314 @OverwriteProtectionBody(false)15 validate(): void {16 if (!validate(this.properties.assigneeId)) {17 throw new ValidationError('assigneeId is invalid');18 }19 }20}
The GetTasksByAssigneeIdQuery
class is responsible for holding query parameters and ensuring their validity through the validate
method.
The QueryHandler
processes the Query and interacts with the repository to fetch the required data. It converts the Query into a request that the repository can handle and returns the results.
The QueryHandler can be found at: Task/src/useCases/read/TaskOverview/application/GetTasksByAssigneeIdQueryHandler.ts
.
1import { OverwriteProtectionBody } from "@codebricks/typebricks";2import { TaskOverview } from "shared/application/readmodels/TaskOverview";3import { TaskOverviewRepository } from "../infrastructure/TaskOverviewRepository";4import { GetTasksByAssigneeIdQuery } from "./GetTasksByAssigneeIdQuery";56export class GetTasksByAssigneeIdQueryHandler {7 constructor(readonly repository: TaskOverviewRepository = new TaskOverviewRepository()) {8 }910 @OverwriteProtectionBody(false)11 async handle(query: GetTasksByAssigneeIdQuery): Promise<TaskOverview[]> {12 const result: TaskOverview[] = await this.repository.getTasksByAssigneeId(13 query.properties.assigneeId,14 );15 return result;16 }17}
The GetTasksByAssigneeIdQueryHandler
class is responsible for:
GetTasksByAssigneeIdQuery
.In the CQRS architecture, the Query Repository is responsible for accessing and retrieving data from the database. It is used to perform read operations, ensuring that queries return the necessary data for processing.
An implementation of a Query Repository can be found at: Task/src/useCases/read/TaskOverview/infrastructure/TaskOverviewRepository.ts
.
1import { OverwriteProtectionBody } from "@codebricks/typebricks";2import { TaskOverview } from "shared/application/readmodels/TaskOverview";3import { TaskOverviewEntity } from "shared/infrastructure/persistence/readmodel/TaskOverviewEntity";4import { AppDataSource } from "shared/infrastructure/persistence/AppDataSource";56export class TaskOverviewRepository {7 @OverwriteProtectionBody(false)8 async getTasksByAssigneeId(assigneeId: string): Promise<TaskOverview[]> {9 return await AppDataSource.manager.find(TaskOverviewEntity, {10 where: {11 assigneeId: assigneeId,12 }13 });14 }15}
ActiveTaskOverviewRepository
Class: This class acts as the Query Repository for the TaskOverviewEntity
. It is responsible for fetching data from the database.
getAll
Method:
ActiveTaskOverviewEntity
from the database.find
method to perform the query. TypeORM is an ORM (Object-Relational Mapping) library that simplifies database interactions in TypeScript applications.TypeORM Notation: The method find
is part of TypeORM’s API for querying the database. It allows specifying conditions to fetch records from the database.
Repository Pattern: Use repositories to encapsulate data access logic and isolate it from the rest of the application. This pattern helps in managing data retrieval and manipulation efficiently.
Error Handling: Implement proper error handling in your repository methods to manage database errors and provide meaningful feedback.