DEV Community

Fiyinfoluwa Ojo
Fiyinfoluwa Ojo

Posted on

Serializers & DTOs: Controlling What Your API Exposes

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

FastAPI uses response_model to filter the output
through the DTO before sending it to the client.

The Difference

Without DTO — /items/full returns:

Without Dto

With DTO — /items returns:

With Dto

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.

GDGoCBowen30dayChallenge

Top comments (0)