Skillversitas

Request Body

For create and update endpoints the client sends a JSON body. In FastAPI you model the body as a Pydantic BaseModel and declare it as a parameter: FastAPI parses the JSON, validates it against the model, and hands you a fully typed object.

A Basic Body

from fastapi import FastAPI
from pydantic import BaseModel, Field

app = FastAPI()

class Item(BaseModel):
    name: str
    description: str | None = None
    price: float = Field(gt=0)
    tags: list[str] = []

@app.post("/items/")
def create_item(item: Item):
    return {"created": item.name, "price": item.price}

POST /items/ with {"name": "Widget", "price": 9.99} creates an item. A missing name or a negative price returns a 422 with itemized errors.

Body with Query and Path Parameters

@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item, full: bool = False):
    return {"item_id": item_id, "full_update": full, "name": item.name}

item_id comes from the path, full from the query string, and item from the JSON body - all in one signature.

Multiple Bodies with Body

By default a single Pydantic model is "the" body. For two body models, wrap them with Body:

from fastapi import Body

class A(BaseModel):
    x: int

class B(BaseModel):
    y: int

@app.post("/pair/")
def pair(a: A = Body(), b: B = Body()):
    return {"x": a.x, "y": b.y}

The client sends {"a": {"x": 1}, "b": {"y": 2}}.

Raw JSON Access

For unstructured payloads, accept the Request and read the body yourself, or declare the parameter as dict or json.RawLike for schemaless JSON:

import json
from fastapi import Request

@app.post("/echo/")
async def echo(request: Request):
    data = await request.json()
    return data

Summary

Model request bodies with Pydantic BaseModels: FastAPI parses, validates, and types the JSON automatically, merges body parameters with path and query parameters in one signature, and supports multiple bodies via Body(). Reach for Request.json() only when the payload has no stable schema.