
Request Bodies: Handling JSON Payloads
Master POST requests in FastAPI. Learn how to use Pydantic models to receive, validate, and process complex JSON data.
Request Bodies: Handling JSON Payloads
When you want to send data from a browser or app to your API (like creating a new user or saving a document), you don't put that data in the URL. You put it in the Request Body.
In FastAPI, we handle request bodies using Pydantic Models.
1. Defining a Schema
Think of a Pydantic model as a "Blueprint" or a "Contract." It tells FastAPI exactly what fields you expect and what their types are.
from pydantic import BaseModel
from typing import Optional
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
2. Receiving the Body
To receive this JSON data in your endpoint, you simply use the model as a type hint for your argument.
@app.post("/items/")
async def create_item(item: Item):
# 'item' is now a real Python object with attributes!
item_dict = item.dict()
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({"total_price": price_with_tax})
return item_dict
The Magic Behind the Scenes:
When a request hits this endpoint:
- FastAPI reads the Request Body as JSON.
- It validates the data against the
Itemmodel. - If a field is missing or the wrong type, it returns a 422 error.
- If valid, it gives you a clean Python object to work with.
3. Nested Structures
AI and Enterprise APIs often need complex, nested data. Pydantic handles this naturally by allowing models to be used as types inside other models.
class Tag(BaseModel):
id: int
label: str
class Item(BaseModel):
name: str
tags: list[Tag] # A list of nested objects!
4. The Body Helper
Sometimes you don't want a whole model for just one field. You can use the Body helper to extract a single value from the JSON payload.
from fastapi import Body
@app.post("/update-status")
async def update_status(status: str = Body(...)):
return {"new_status": status}
Visualizing the Flow
graph LR
A["Raw JSON Body"] --> B["FastAPI / Pydantic"]
B -- Validation Fail --> C["422 Unprocessable Entity"]
B -- Validation Pass --> D["Python Object (Code)"]
D --> E["Business Logic / Database"]
Summary
BaseModelis the starting point for all request bodies.- Type Validation is automatic and strict.
- Nested Models allow for extremely complex data structures.
- Documentation: Your schemas are automatically used to generate the "Request Body" section in Swagger UI.
In the next lesson, we wrap up Module 4 with Exercises to test your routing and payload skills.
Exercise: The User Signup
Design a Pydantic model for a User Signup. Requirements:
username(string, required)email(string, required)password(string, required)bio(string, optional)age(integer, optional)
How would your FastAPI function signature look to receive this data in a POST /signup endpoint?