Skip to content

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.ts ensures consistent options across all modules.