Sometimes you want to send more than one piece of information in the body of a request. FastAPI lets you handle multiple body parameters easily.
Multiple path parameters in FastAPI
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str price: float class User(BaseModel): username: str email: str @app.post("/create") async def create_item_user(item: Item, user: User): return {"item": item, "user": user}
Each body parameter must be a Pydantic model or a simple type.
FastAPI automatically reads and validates each parameter from the request body.
item and user. FastAPI reads both from the JSON body.from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str price: float class User(BaseModel): username: str email: str @app.post("/create") async def create_item_user(item: Item, user: User): return {"item_name": item.name, "user_email": user.email}
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Product(BaseModel): title: str quantity: int class Customer(BaseModel): name: str phone: str @app.post("/order") async def place_order(product: Product, customer: Customer): return {"product": product.title, "customer": customer.name}
This FastAPI app defines two models: Item and User. The endpoint /create accepts both as body parameters. It returns a message combining their data.
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str price: float class User(BaseModel): username: str email: str @app.post("/create") async def create_item_user(item: Item, user: User): return { "message": f"User {user.username} created item {item.name} costing ${item.price}" }
When sending the request, the JSON body must include both parameters as separate JSON objects.
Example request body:
{
"item": {"name": "Book", "price": 12.99},
"user": {"username": "alice", "email": "alice@example.com"}
}
FastAPI uses the parameter names to find the matching keys in the JSON body.
FastAPI lets you accept multiple body parameters by defining them as function arguments with Pydantic models.
Each parameter is read from the JSON body using its name as the key.
This helps organize and validate complex request data easily.
Practice
Solution
Step 1: Understand FastAPI body parameter handling
FastAPI reads JSON body parameters by matching function argument names and types, typically Pydantic models.Step 2: Accept multiple parameters
By defining multiple function parameters with Pydantic models, FastAPI expects each as a separate JSON object in the request body.Final Answer:
Define multiple function parameters each with a Pydantic model type. -> Option CQuick Check:
Multiple body parameters = multiple Pydantic model arguments [OK]
- Trying to pass multiple JSON objects in one body without models
- Using query parameters instead of body for complex data
- Combining all data into one string and parsing manually
user and item in a FastAPI endpoint?Solution
Step 1: Understand parameter declaration for multiple bodies
FastAPI requires explicit use ofBody()for multiple body parameters to distinguish them.Step 2: Check each option
async def endpoint(user: User = Body(), item: Item = Body()): correctly uses= Body()for both parameters. async def endpoint(user: User, item: Item): missesBody(), so FastAPI treats only the first as body. Options B and D incorrectly mixQuery()andBody().Final Answer:
async def endpoint(user: User = Body(), item: Item = Body()): -> Option AQuick Check:
Multiple bodies require= Body()[OK]
= Body() for each body parameter to avoid errors [OK]- Omitting
= Body()for multiple body parameters - Mixing query and body decorators incorrectly
- Using default values without
Body()
{"user": {"name": "Alice"}, "item": {"id": 5}}?
from fastapi import FastAPI, Body
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
class Item(BaseModel):
id: int
@app.post("/create")
async def create(user: User = Body(), item: Item = Body()):
return {"user_name": user.name, "item_id": item.id}Solution
Step 1: Understand parameter parsing
FastAPI matches the JSON keys "user" and "item" to the parametersuseranditemrespectively, parsing each into the corresponding Pydantic model.Step 2: Check the return statement
The function returns a dictionary with keys "user_name" and "item_id" extracted from the parsed models, so the response JSON will contain these values.Final Answer:
{"user_name": "Alice", "item_id": 5} -> Option DQuick Check:
Parsed models return selected fields as response [OK]
- Expecting the entire input JSON as output
- Confusing 422 error with correct parsing
- Assuming server error without code issues
user and item:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
class Item(BaseModel):
id: int
@app.post("/add")
async def add(user: User, item: Item):
return {"user": user, "item": item}Solution
Step 1: Check parameter declarations
When multiple body parameters are declared, each must use= Body()to tell FastAPI to parse them from the body separately.Step 2: Analyze the return statement
Returning Pydantic models directly is allowed; FastAPI serializes them automatically, so no error here.Final Answer:
Missing= Body()for multiple body parameters causes validation error. -> Option BQuick Check:
Multiple bodies require= Body()[OK]
= Body() for each body parameter to fix errors [OK]- Omitting
= Body()for multiple body parameters - Thinking Pydantic models can't be returned directly
- Confusing async with sync function requirements
user with fields name and age, and preferences with optional color and food. Which code correctly defines the endpoint and handles missing optional fields gracefully?Solution
Step 1: Define optional fields correctly
Usingstr | None = Nonesets optional fields with default None, allowing missing keys without error.Step 2: Declare multiple body parameters with
This tells FastAPI to parse both= Body()userandpreferencesfrom the JSON body separately.Step 3: Return dict representations for JSON serialization
Calling.dict()on Pydantic models converts them to plain dicts for clean JSON output.Final Answer:
Defines optional fields with `str | None = None`, uses `= Body()` for multiple parameters, and returns `.dict()` representations. -> Option AQuick Check:
Optional fields + multiple bodies + dict() return = class User(BaseModel): name: str age: int class Preferences(BaseModel): color: str | None = None food: str | None = None @app.post("/profile") async def profile(user: User = Body(), preferences: Preferences = Body()): return {"user": user.dict(), "preferences": preferences.dict()} [OK]
field: type | None = None for optional fields [OK]- Not marking optional fields with default None
- Omitting
= Body()for multiple parameters - Returning Pydantic models without converting to dict
Ready to prove it?
Pass the test and this pattern moves unknown
