FastAPI Request Body

The request body is the data sent by 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 performing data validation, conversion, and documentation generation.


The difference between request body and query parameters

Data Transfer MethodsPositionApplicable scenariosHTTP Methods
Path ParameterURL Path/items/5Identify resourceGET, PUT, DELETE, etc.
Query ParameterIn the URL?key=valueOptional parameters such as filtering and paginationMainly GET
request bodyThe JSON data of the requestSubmitting Complex DataPOST、PUT、PATCH

Sending Data Should UsePOST(most common),PUT、DELETEorPATCHAlthough FastAPI technically supports GET requests carrying a request body, this does not conform to HTTP specifications, and Swagger UI will not show request body documentation for GET requests.


Declaring the request body with a Pydantic model

Import BaseModel

from pydantic import BaseModel

2. Create data model

Define a class inheritingBaseModelFor the class, declare all attributes using Python standard types:

Example

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


# Define the request body data model
class Item(BaseModel):
    name: str               # Required: Product name
    description: str | None = None  # Optional: Product description
    price: float            # Required: Product 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 (e.g.,description、tax)
  • Attributes without default values are required (e.g.,name、price)

The following JSON are all valid request bodies:

// 包含所有字段
{
    "name": "Foo",
    "description": "可选描述",
    "price": 45.2,
    "tax": 3.5
}

// 省略可选字段
{
    "name": "Foo",
    "price": 45.2
}

FastAPI's handling of the request body

Just by declaring Python types, FastAPI can automatically do the following:

FeaturesDescription
Read request bodyRead the data from the request in JSON format
Type conversionConvert the data to the declared types (e.g., string to float)
Data verificationValidate the data, and return clear error messages when invalid
Assign parameterAssign the validated data to the function parameters, providing editor autocompletion
Generate documentationAutomatically generate a JSON Schema, which appears in the API documentation

Use model attributes

Inside the path operation function, you can access all attributes of the model just like operating on a normal 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):
    # Directly access model attributes
    item_dict = item.model_dump()  # Pydantic v2 serialization method
    if item.tax:
        # Calculate price including tax
        price_with_tax = item.price + item.tax
        item_dict.update({"price_with_tax": price_with_tax})
    return item_dict

Pydantic v2 Usagemodel_dump()Replaces the v1dict()method to serialize model data.model_dump()Return a dictionary containing all fields of the model.


Request body + path parameters

You can declare path parameters and a request body at the same time, and FastAPI will automatically get the data from the correct places:

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


# Using Both Path Parameters and Request Body
@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_idin the path{item_id}appears in -> path parameter
  • itemThe type is a Pydantic model -> request body

Request body + path parameters + query parameters

All three can be used simultaneously:

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


# Using path parameters, query parameters, and request body at the same time
@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 conditionParameter source
Parameter names in the path{}declared inPath Parameter
The parameter is a single type (int、str、booletc.)Query Parameter
If the parameter type is a Pydantic modelrequest body

Summary

Core points of the request body:

  • Using Pydantic'sBaseModelDefine request body structure
  • Fields with default values are optional; fields without default values are required.
  • The request body can be used together with path parameters and query parameters.
  • FastAPI automatically performs data validation, type conversion, and documentation generation.
  • Pydantic v2 Usagemodel_dump()Perform serialization
other extensions