Skip to content

FastAPI Response Model Fix

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about FastAPI Response Model Fix. We cover key concepts, practical examples, and best practices.

The Problem

FastAPI endpoints return Pydantic models by default, but they may expose internal fields (password hashes, secret IDs) or include fields you don't want the client to see.

Quick Fix

Wrong — returning the full model

from pydantic import BaseModel

class User(BaseModel):
    id: int
    username: str
    email: str
    password_hash: str  # Exposed to client!

@app.get("/users/{user_id}")
async def get_user(user_id: int):
    user = await fetch_user(user_id)
    return user  # Returns password_hash to client

Output: API response includes password_hash. A serious security vulnerability.

Correct — response_model filtering

from pydantic import BaseModel

class UserInDB(BaseModel):
    id: int
    username: str
    email: str
    password_hash: str

class UserOut(BaseModel):
    id: int
    username: str
    email: str

@app.get("/users/{user_id}", response_model=UserOut)
async def get_user(user_id: int):
    user = await fetch_user(user_id)  # Returns UserInDB
    return user  # FastAPI filters to UserOut fields

Output: Response only includes id, username, email. password_hash is excluded.

response_model with list

@app.get("/users", response_model=List[UserOut])
async def list_users():
    users = await fetch_all_users()
    return users

response_model_exclude and include

@app.get(
    "/users/{user_id}",
    response_model=UserOut,
    response_model_exclude={"email"},  # Exclude email from this response
)
async def get_user_public(user_id: int):
    user = await fetch_user(user_id)
    return user

Different responses for different status codes

from fastapi.responses import JSONResponse

class ErrorResponse(BaseModel):
    error: str
    code: int

@app.get(
    "/users/{user_id}",
    response_model=UserOut,
    responses={
        404: {"model": ErrorResponse},
    },
)
async def get_user(user_id: int):
    user = await fetch_user(user_id)
    if not user:
        return JSONResponse(status_code=404, content={"error": "Not found", "code": 404})
    return user

Response model with ORM mode

class UserOut(BaseModel):
    id: int
    username: str
    email: str

    class Config:
        from_attributes = True  # Enables ORM mode

@app.get("/users/{user_id}", response_model=UserOut)
async def get_user(user_id: int):
    user = await db.query(UserORM).filter(UserORM.id == user_id).first()
    return user  # ORM object converted to Pydantic automatically

Prevention

  • Always define a separate response model that excludes sensitive fields.
  • Use response_model on every endpoint that returns data.
  • Use from_attributes = True in response models for ORM integration.

Common Mistakes with response model

  1. Mixing let bindings with <- bindings in do notation, producing type errors
  2. Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
  3. Non-exhaustive pattern matches that compile with warnings then crash at runtime

These mistakes appear frequently in real-world FASTAPI code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### What happens if the response doesn't match response_model?

FastAPI validates and filters the response. Missing fields get defaults (if set). Extra fields are removed. Type mismatches may cause errors.

Can I use response_model with background tasks?

Yes. The response_model filters the response before returning it. Background tasks run after.

Is response_model applied before or after serialization?

Before. FastAPI filters the data using the response_model, then serializes to JSON.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro