A DTO (data transfer object) is a plain data shape for moving data across a boundary. An HTTP request body or response is a typical example. It has no behaviour, except maybe validation annotations. You design it for the API consumer.
An entity is a domain or database object. It has an identity, behaviour and invariants (rules that must always be true). The business and the database decide its shape.
You shouldn't return ORM entities directly, because it ties your public API to your database schema. For example, renaming a column becomes a breaking API change. It also causes these risks:
- It can leak sensitive fields such as
passwordHash. - Serialisation can trigger lazy-loaded relations or huge object graphs. Lazy loading means related data is fetched from the database only when the code reads it.
- On input, it makes mass assignment easy: a client sends extra fields like
isAdmin, and they get saved.
Instead, map explicitly in three steps:
- request DTO
- domain operation
- response DTO built from the entity
The mapping code is a small price. In return, you get a stable API and a model you can change freely.
- A DTO is a data shape with no behaviour, used to cross a boundary.
- An entity has identity, behaviour and a mapping to the database.
- Returning entities ties your API to your database schema.
- The risks are leaked fields, lazy loading and mass assignment.
- Map explicitly from request DTO to domain to response DTO.
Read more