Fastapi Request Body
Request body is data sent from the client to the API. When you need to receive JSON data from the client, use the request body to pass it. FastAPI uses Pydantic models to declare the structure of the request body, automatically completing data validation, conversion, and documentation generation.
* * *
## Difference Between Request Body and Query Parameters
| Data Transfer Method | Location | Use Case | HTTP Method |
| --- | --- | --- | --- |
| Path Parameter | URL path `/items/5` | Identify resources | GET, PUT, DELETE, etc. |
| Query Parameter | URL `?key=value` | Filtering, pagination, and other optional parameters | Mainly GET |
| Request Body | Request JSON data | Submit complex data | POST, PUT, PATCH |
> Use `POST` (most common), `PUT`, `DELETE`, or `PATCH` to send data. Although FastAPI technically supports GET requests with request bodies, this violates HTTP specifications, and Swagger UI will not display request body documentation for GET requests.
* * *
## Declare Request Body Using Pydantic Model
### 1. Import BaseModel
from pydantic import BaseModel
### 2. Create Data Model
Define a class that inherits from `BaseModel`, using Python standard types to declare all attributes:
## Example
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# Define request body data model
class Item(BaseModel):
name: str# Required: item name
description: str | None=None# Optional: item description
price: float# Required: item price
tax: float | None=None# Optional: tax
@app.post("/items/")
async def create_item(item: Item):
return item
The rules for whether attributes are required are the same as for query parameters:
* Attributes with default values are optional (like `description`, `tax`)
* Attributes without default values are required (like `name`, `price`)
The following JSON are all valid request bodies:
// Include all fields{ "name": "Foo", "description": "Optional description", "price": 45.2, "tax": 3.5}// Omit optional fields{ "name": "Foo", "price": 45.2}
* * *
## FastAPI's Processing of Request Body
Just by declaring Python types, FastAPI can automatically complete the following:
| Feature | Description |
| --- | --- |
| Read Request Body | Read data from the request in JSON format |
| Type Conversion | Convert data to declared types (e.g., string to float) |
| Data Validation | Validate data validity, return clear error messages when invalid |
| Assign Parameters | Assign validated data to function parameters, get editor auto-completion |
| Generate Documentation | Auto-generate JSON Schema, appears in API documentation |
* * *
## Using Model Attributes
Inside the path operation function, you can access all model attributes like operating on a regular Python object:
## Example
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None=None
price: float
tax: float | None=None
@app.post("/items/")
async def create_item(item: Item):
# Access model attributes directly
item_dict = item.model_dump()# Serialization method for Pydantic v2
if item.tax:
# Calculate price with tax
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
> Pydantic v2 uses `model_dump()` instead of v1's `dict()` method to serialize model data. `model_dump()` returns a dictionary containing all fields of the model.
* * *
## Request Body + Path Parameters
You can declare both path parameters and request body at the same time, FastAPI will automatically get data from the correct location:
## Example
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None=None
price: float
tax: float | None=None
# Use path parameter and request body together
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return{"item_id": item_id,"item_name": item.name}
FastAPI recognition rules:
* `item_id` appears in path `{item_id}` -> path parameter
* `item`'s type is Pydantic model -> request body
* * *
## Request Body + Path Parameters + Query Parameters
All three can be used together:
## Example
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None=None
price: float
tax: float | None=None
# Use path parameter, query parameter, and request body together
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: str | None=None):
result ={"item_id": item_id, **item.model_dump()}
if q:
result.update({"q": q})
return result
FastAPI's complete parameter recognition rules:
| Recognition Condition | Parameter Source |
| --- | --- |
| Parameter name declared in path `{}` | Path parameter |
| Parameter is a single type (`int`, `str`, `bool`, etc.) | Query parameter |
| Parameter type is Pydantic model | Request body |
* * *
## Summary
Key points of request body:
* Use Pydantic's `BaseModel` to define request body structure
* Fields with default values are optional, fields without default values are required
* Request body can be used together with path parameters and query parameters
* FastAPI automatically completes data validation, type conversion, and documentation generation
* Pydantic v2 uses `model_dump()` for serialization
YouTip