Appearance
Mapper DTO Options
Overview
All toDto methods on mappers accept an optional IMapperOptions parameter that controls runtime behavior when converting a domain entity to a response DTO. The default is to validate the output via Zod schema parse.
Interface
Defined in apps/api/src/shared/infrastructure/mapper/mapper.base.ts:
ts
export interface IMapperOptions {
validate?: boolean;
}
export const DefaultMapperOptions: IMapperOptions = {
validate: true,
};Usage Pattern
Every mapper's toDto method follows this signature:
ts
static toDto(
domain: SomeEntity,
options: IMapperOptions = DefaultMapperOptions,
): SomeResponseDto {
const dto = { /* map fields */ };
return options.validate ? someResponseSchema.parse(dto) : dto;
}validate: true (default)
The assembled plain object is passed through schema.parse(dto). This throws a ZodError if the output does not conform to the schema, acting as a runtime contract check before the DTO leaves the server.
validate: false
Skips schema parsing. Useful in internal pipelines or tests where the caller already guarantees shape correctness and the overhead or strict coercion of Zod is undesirable.
Examples
Session mapper (session.mapper.ts):
ts
static toDto(
domain: Session,
isCurrent: boolean,
options: IMapperOptions = DefaultMapperOptions,
): SessionResponseDto {
const dto = { id: domain.id, isCurrent, ... };
return options.validate ? sessionResponseSchema.parse(dto) : dto;
}Agency mapper (agency.mapper.ts):
ts
static toDto(
domain: Agency,
options: IMapperOptions = DefaultMapperOptions,
): AgencyResponseDto {
const dto = { id: domain.id, name: domain.name, ... };
return options.validate ? agencyResponseSchema.parse(dto) : dto;
}Decision Rationale
- Validation by default prevents malformed DTOs from reaching the HTTP response layer.
- The opt-out flag avoids double-parsing in contexts that already validated upstream (e.g., test fixtures, internal service calls).
- Keeping the interface in
mapper.base.tsensures consistent options across all modules.