DEV Community

Cover image for Day 3: Request Body & Pydantic Explained with Real-World Context
Utkarsh Rastogi
Utkarsh Rastogi

Posted on • Edited on

Day 3: Request Body & Pydantic Explained with Real-World Context

Welcome to Day 3 of our FastAPI journey! Yesterday, we explored how to use path parameters to handle dynamic URLs.

Today, we’re entering the world of Request Bodies and Pydantic β€” the backbone of data validation in FastAPI.


🧠 Why Do We Need Request Bodies?

Let’s imagine you're building an online registration form for a new user. You need details like name, email, and age. These details are not passed in the URL but rather sent in the body of a POST request.

This is where request bodies and Pydantic models come into play in FastAPI.


🧩 Real-World Analogy: Pydantic is the Bouncer at a Club

Think of your API like a nightclub. You can’t just let anyone in. The bouncer at the door checks if you're:

  • Old enough (age)
  • On the list (valid email)
  • Actually a real person (non-empty name)

Just like that, Pydantic is your API’s gatekeeper β€” it checks if the incoming request body has the correct structure and data types.


πŸ”§ Step-by-Step: Create a /user POST Endpoint

We'll create a FastAPI app that accepts a JSON body with user details.

πŸ“ Create a file called user.py:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# 🎯 Step 1: Define your request body schema using Pydantic
class User(BaseModel):
    name: str
    email: str
    age: int

# 🎯 Step 2: Create a POST endpoint to accept the request body
@app.post("/user")
def create_user(user: User):
    return {
        "message": f"Welcome, {user.name}!",
        "email": user.email,
        "age": user.age
    }
Enter fullscreen mode Exit fullscreen mode

πŸš€ Test Your Endpoint

πŸ–₯️ Start the FastAPI server:

uvicorn user:app --host 0.0.0.0 --port 9002 --reload
Enter fullscreen mode Exit fullscreen mode

🌐 Open your browser and visit the interactive docs:

http://localhost:9002/docs

πŸ“€ Try sending this sample JSON:

{
  "name": "Utkarsh",
  "email": "[email protected]",
  "age": 28
}
Enter fullscreen mode Exit fullscreen mode

Input

Output:

Output

βœ… FastAPI will automatically validate the request and return a structured response or helpful error messages.


πŸ§ͺ Add Validation with Pydantic

Let’s enhance the model with proper validation using EmailStr, default values, and field constraints.

πŸ”§ Prerequisite: Install email-validator

To use EmailStr for validating emails, you must install the email-validator package.

Run this command in your terminal:

pip install pydantic[email]
Enter fullscreen mode Exit fullscreen mode

πŸ”§ Step-by-Step: Create a /user POST Endpoint

We'll create a FastAPI app that accepts a JSON body with user details.

πŸ“ Create a file called user.py:

from fastapi import FastAPI
from pydantic import BaseModel, EmailStr, Field
from typing import Optional

app = FastAPI()

class User(BaseModel):
    name: str = Field(..., min_length=2, max_length=50)
    email: EmailStr
    age: Optional[int] = Field(None, ge=18, le=100)


@app.post("/user")
def create_user(user: User):
    return {
        "message": f"Welcome, {user.name}!",
        "email": user.email,
        "age": user.age
    }
Enter fullscreen mode Exit fullscreen mode

πŸ” Explanation:

  • name: Required string with a minimum length of 2 and a maximum of 50.
  • email: Must be a valid email address (EmailStr from Pydantic).
  • age: Optional integer; if provided, it must be between 18 and 100.

πŸš€ Test Your Endpoint

πŸ–₯️ Start the FastAPI server:

uvicorn user:app --host 0.0.0.0 --port 9004 --reload
Enter fullscreen mode Exit fullscreen mode

🌐 Open your browser and visit the interactive docs:

http://localhost:9004/docs

πŸ“€ Try sending this sample JSON:

{
  "name": "Utkarsh",
  "email": "[email protected]",
  "age": 16
}
Enter fullscreen mode Exit fullscreen mode

Input Age

Output:

Output Error


🌍 Real-World Example – Feedback API

from fastapi import FastAPI
from pydantic import BaseModel, EmailStr, Field

app = FastAPI()

class Feedback(BaseModel):
    name: str
    email: EmailStr
    message: str = Field(..., min_length=10)

@app.post("/feedback")
def submit_feedback(feedback: Feedback):
    return {
        "status": "received",
        "from": feedback.name,
        "email": feedback.email
    }
Enter fullscreen mode Exit fullscreen mode

Input:

{
  "name": "Utkarsh",
  "email": "[email protected]",
  "message": "Great job with the FastAPI series!"
}

Enter fullscreen mode Exit fullscreen mode

Output:

Job


πŸ“¦ Nested Models Example – Customer with Address

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Address(BaseModel):
    city: str
    pincode: int

class Customer(BaseModel):
    name: str
    address: Address

@app.post("/customer")
def create_customer(customer: Customer):
    return {"msg": f"{customer.name} from {customer.address.city} added."}

Enter fullscreen mode Exit fullscreen mode

Input:

{
  "name": "Utkarsh",
  "address": {
    "city": "Mumbai",
    "pincode": 110
  }
}

Enter fullscreen mode Exit fullscreen mode

Output:

Feefdback


🧠 Recap

Concept Purpose
BaseModel Define and validate data models
EmailStr Validate email format
Optional Make fields optional
Field() Add constraints like min, max, default
Nested Models Model complex JSON structures

πŸ™ Credits

Huge thanks to the FastAPI Official Documentation by SebastiΓ‘n RamΓ­rez (@tiangolo) β€” the best place to learn and explore everything about FastAPI.


πŸ‘¨β€πŸ’» About Me

Hey there! I’m Utkarsh Rastogi, an AWS Community Builder and passionate cloud-native enthusiast who loves building scalable backend systems and sharing knowledge with the community.

πŸ”— Connect with me: Utkarsh Rastogi


πŸ’¬ Share Your Thoughts – I'd Love Your Feedback!

If you enjoyed today's post or learned something new, I'd truly appreciate it if you leave a comment or share your thoughts πŸ‘‡

Your feedback, questions, or even a quick β€œπŸ”₯ Loved this!” keeps me motivated to continue this journey and share more in the upcoming #FastAPIDaily posts.

βœ… What did you find most helpful?

βœ… Anything you'd like explained in the next part?

βœ… Suggestions for improvement? I’m all ears! πŸ™Œ

Let’s grow and learn together β€” one FastAPI day at a time πŸš€


Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.