DTOs (Data Transfer Objects)
DTOs (Data Transfer Objects)
What: Objects that carry data between layers (API ↔ service ↔ DB). Data only, no behavior (or minimal validation).
Why: Decouple internal models from API/contracts. Different DTOs per operation (create vs update vs response). Control what goes in/out; validate at the boundary.
- Input DTOs: e.g.
CreateUserDTO,UpdateUserDTO— what the API accepts. - Output DTOs: e.g.
UserResponseDTO— what we return (no secrets, stable shape). - Dataclasses / Pydantic: good fit. Optional: immutable
@dataclass(frozen=True).
Validation: At the boundary (controller/API). Pydantic or Marshmallow for schema + validation.
Mapping: Model → DTO and DTO → model in a mapper layer or small functions. Keeps controllers thin and services model-agnostic.
Don’t: Put business logic in DTOs. Expose internal IDs or sensitive fields in response DTOs.
Pagination: e.g. { items, total, page, page_size } as a DTO so the API contract is stable.