Skip to main content
FastrAPI leverages Pydantic models for automatic request validation, type checking, and data serialization. This integration provides type-safe APIs with automatic validation and documentation generation.

Basic validation

Define Pydantic models to validate incoming request data. FastrAPI automatically validates request bodies against your model schemas.
main.py
from pydantic import BaseModel
from fastrapi import FastrAPI

app = FastrAPI()

class User(BaseModel):
    name: str
    age: int

@app.post("/users")
def create_user(user: User):
    return {
        "message": f"Created user {user.name}, age {user.age}"
    }

if __name__ == "__main__":
    app.serve("127.0.0.1", 8080)
FastrAPI automatically validates the request body against the User model. If validation fails, it returns a 422 Unprocessable Entity response with detailed error information.

Multiple model validation

You can use multiple Pydantic models in a single endpoint. Each model will be validated independently.
from pydantic import BaseModel
from fastrapi import FastrAPI

app = FastrAPI(openapi_url="/api-docs/openapi.json")

class User(BaseModel):
    name: str
    age: int

class Address(BaseModel):
    street: str
    city: str
    zip: str

@app.post("/register")
def register(user: User, address: Address):
    return {
        "msg": f"Registered {user.name}, age {user.age}, living at {address.street}, {address.city} {address.zip}"
    }

app.serve("127.0.0.1", 8080)
The request body should include fields from both models:
{
  "name": "John Doe",
  "age": 30,
  "street": "123 Main St",
  "city": "San Francisco",
  "zip": "94102"
}

Validation errors

When validation fails, FastrAPI returns a 422 status code with detailed error information showing which fields failed validation and why.
@app.post("/items")
def create_item(item: Item):
    return item.dict()

Field validation with Pydantic

Use Pydantic’s field validators and constraints to enforce business rules:
from pydantic import BaseModel, Field, field_validator
from fastrapi import FastrAPI

app = FastrAPI()

class Product(BaseModel):
    name: str = Field(min_length=3, max_length=50)
    price: float = Field(gt=0, description="Price must be greater than zero")
    quantity: int = Field(ge=0, le=10000)
    
    @field_validator('name')
    def name_must_not_be_empty(cls, v):
        if not v.strip():
            raise ValueError('Name cannot be empty')
        return v.strip()

@app.post("/products")
def create_product(product: Product):
    return {"product": product.dict()}

Nested models

Pydantic models can be nested for complex data structures:
from pydantic import BaseModel
from typing import List
from fastrapi import FastrAPI

app = FastrAPI()

class Item(BaseModel):
    name: str
    price: float

class Order(BaseModel):
    order_id: int
    items: List[Item]
    total: float

@app.post("/orders")
def create_order(order: Order):
    return {
        "message": f"Order {order.order_id} created with {len(order.items)} items",
        "total": order.total
    }

Optional fields and defaults

Use Python’s Optional type hint and default values for optional fields:
from pydantic import BaseModel
from typing import Optional
from fastrapi import FastrAPI

app = FastrAPI()

class UserProfile(BaseModel):
    username: str
    email: str
    bio: Optional[str] = None
    is_active: bool = True
    age: Optional[int] = None

@app.post("/profiles")
def create_profile(profile: UserProfile):
    return profile.dict()

Response validation

You can also use Pydantic models to validate response data, ensuring your API returns consistent, well-structured responses:
from pydantic import BaseModel
from fastrapi import FastrAPI
from fastrapi.responses import JSONResponse

app = FastrAPI()

class UserResponse(BaseModel):
    id: int
    username: str
    email: str

@app.get("/users/{user_id}")
def get_user(user_id: int) -> JSONResponse:
    user = UserResponse(
        id=user_id,
        username="johndoe",
        email="[email protected]"
    )
    return JSONResponse(user.dict())

How validation works

FastrAPI’s validation process is powered by Rust for maximum performance:
1

Request parsing

The incoming request body is parsed as JSON and converted to Python objects.
2

Model detection

FastrAPI detects Pydantic models in your function signature by checking for model_validate or model_fields attributes (src/pydantic.rs:61-85).
3

Validation

Each Pydantic model validates its corresponding fields from the request body. If validation fails, a 422 response is returned immediately (src/pydantic.rs:34-40).
4

Handler execution

Once all validations pass, the handler function is called with the validated model instances.

Performance considerations

FastrAPI uses a “fast path” optimization for routes without Pydantic validation, providing maximum performance when validation isn’t needed. Routes with Pydantic models are still extremely fast due to Rust’s efficient validation handling.
# Fast path: No validation
@app.get("/status")
def status():
    return {"status": "ok"}

# Validated path: Still very fast
@app.post("/users")
def create_user(user: User):
    return user.dict()
The fast path detection is automatic. FastrAPI analyzes your route handlers at startup to determine the optimal execution path (src/pydantic.rs:170).

Best practices

Be specific with your field types to get better validation and documentation:
from pydantic import BaseModel, EmailStr, HttpUrl
from typing import Literal

class User(BaseModel):
    email: EmailStr  # Not just str
    website: HttpUrl
    role: Literal["admin", "user", "guest"]
Use Field descriptions to generate better API documentation:
from pydantic import BaseModel, Field

class Product(BaseModel):
    name: str = Field(description="Product name")
    price: float = Field(gt=0, description="Price in USD")
Configure model behavior with Pydantic’s Config class:
class User(BaseModel):
    name: str
    age: int
    
    class Config:
        str_strip_whitespace = True
        validate_assignment = True

Request handling

Learn about request processing in FastrAPI

Response types

Explore different response formats

Error handling

Handle validation errors gracefully

API reference

Complete API documentation

Build docs developers (and LLMs) love