What is a DTO?
A DTO (Data Transfer Object) controls exactly what data
leaves your API. Your database model might have 20 fields,
but your API should only expose what the client needs.
Never expose internal fields to the outside world.
The Problem
My Item model has these fields:
- id, name, description, price, created_at
- internal_db_id <- sensitive internal field
- deleted_at <- sensitive internal field
Without a DTO, all of these get returned to the client.
That's a security risk and a messy API contract.
The Solution : Pydantic DTO
class ItemResponseDTO(BaseModel):
id: int
name: str
price: float
class Config:
from_attributes = True
This DTO only exposes id, name, and price.
Everything else is hidden automatically.
Applying the DTO to the Endpoint
@app.get("/items", response_model=List[ItemResponseDTO])
def get_all_items():
db = SessionLocal()
items = db.query(Item).all()
db.close()
return items
FastAPI uses response_model to filter the output
through the DTO before sending it to the client.
The Difference
Without DTO — /items/full returns:
With DTO — /items returns:
See how internal_db_id and deleted_at are completely
hidden in the DTO response? That's the power of serializers.
Lessons Learned
Always define what your API exposes explicitly.
The database model and the API response model
should never be the same thing in production systems.
Day 8 done. 22 more to go.


Top comments (0)