🍇Unit 12: Request Body - List Fields and Nested Models
Introduction
In FastAPI, you can define request bodies with complex structures using Pydantic models. These can include fields and nested models. In the following sections, this unit will show how to implement list fields and nested models.
List fields
Let's take a look at the following program:
# Note: This program is implemented in Python 3.12
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: list[str] = []
@app.post("/update-item/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item, "message": "Item updated successfully"}
return results
To evaluate the program, you can compose a request in Postman as shown in Fig. 1. The request body can be as follows:
{
"name": "Green Apple",
"description": "A type of fruit",
"price": 50000,
"tax": 2500,
"tags": ["fruit", "apple"]
}

Nested models
In the following program, we define two classes, i.e., Image
and Item
, and they have a HAS-A relationship. In Image
class, the metadata
is declared as a list of dictionary (key-value pairs).
# Note: This program is implemented in Python 3.12
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
url: str
metadata: list[dict[str, str]]
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: list[str] = []
image: Image = None
@app.post("/update-item/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item, "message": "Item updated successfully"}
return results
The request body to evaluate the above program is as follows. You should note how we compose the metadata
values. Fig. 2 shows the results when evaluating the program in Postman.
{
"name": "Green Apple",
"description": "A type of fruit",
"price": 50000,
"tax": 2500,
"tags": [
"fruit",
"apple"
],
"image": {
"url": "example.com",
"metadata": [
{
"File type": "JPEG",
"MIME type": "image/jpeg"
}
]
}
}

Example program
In this example:
We define a Pydantic model
Item
with fieldsname
,description
,price
, andtax
.We then define another Pydantic model
Order
that contains a list ofItem
objects along withcustomer_name
andshipping_address
.In the route
/order/
, we accept POST requests with a request body of typeOrder
.When a request is made to
/order/
, FastAPI automatically validates the request body against theOrder
model and gives you an instance ofOrder
in the route functioncreate_order
.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
class Order(BaseModel):
items: list[Item]
customer_name: str
shipping_address: str
@app.post("/order/")
async def create_order(order: Order):
return {"order_details": order}
Summary
In this unit, we have introduced how to enhance request body in FastAPI to allow the server program to capture more complex inputs using list fields and nested models in combination with Pydantic model.
Last updated