Topics in this subject
FastAPI 3 min read Updated 11 Aug 2026

Request Body and Responses

Handling JSON payloads, multiple models, and customizing HTTP status codes.

🧑‍🏫 Sabse pehle — simple mein samjho#

Jab client server ko bada data bhejta hai (jaise poora signup form), to wo URL mein nahi bhejta, balki request ki "Body" (JSON format) mein bhejta hai. Humne dekha ki Pydantic ise kitne easily handle karta hai. Par kabhi-kabhi humein response bhejtay waqt status code bhi change karna padta hai (jaise "201 Created" jab naya user bane) ya specific format set karna padta hai (response_model). Ye sab route decorator ke andar hi control hota hai.

1. Handling the Request Body#

We use Pydantic models to define the shape of the incoming body. But what if you want to accept multiple different objects in the same request?

FastAPI handles this beautifully. You just pass multiple Pydantic models to the function. FastAPI will automatically structure the expected JSON body to nest these objects.

from pydantic import BaseModel

class User(BaseModel):
    username: str
    password: str

class Item(BaseModel):
    name: str
    price: float

@app.post("/users/{user_id}/items")
async def create_item_for_user(
    user_id: int,          # Path parameter
    user: User,            # Request Body part 1
    item: Item,            # Request Body part 2
    importance: int = 1    # Query parameter
):
    # FastAPI automatically expects a JSON body like:
    # {
    #   "user": { "username": "tarun", "password": "123" },
    #   "item": { "name": "laptop", "price": 1000 }
    # }
    return {"item_name": item.name, "owner": user.username}

2. Customizing the Response Status Code#

By default, FastAPI returns a 200 OK status for successful requests. If you are creating a new resource in a database via a POST request, you should return a 201 Created status code. You define this in the route decorator.

from fastapi import status

# Using the status enum prevents typos (like 201 vs 210)
@app.post("/items/", status_code=status.HTTP_201_CREATED)
async def create_item(name: str):
    return {"name": name, "message": "Item created successfully"}

3. The response_model (Filtering Out Data)#

This is a critical security feature. Suppose your database query returns a User object that includes their hashed password. You DO NOT want to send the hashed password back to the frontend in the JSON response!

You can define a separate Pydantic model for the response, and FastAPI will automatically filter out any fields that are not defined in that response model, even if your function returns them!

class UserInDB(BaseModel):
    username: str
    email: str
    hashed_password: str # Secret!

class UserResponse(BaseModel):
    username: str
    email: str
    # hashed_password is omitted here

# We tell FastAPI to format the output using UserResponse
@app.post("/users/", response_model=UserResponse)
async def create_user():
    # We fetch/create the user (includes the password)
    user = UserInDB(username="tarun", email="t@t.com", hashed_password="xyz")
    
    # We return the whole object, BUT FastAPI will strip out the password before sending it to the client!
    return user