FastAPI · Lesson 2 of 5
Path, Query and Body Parameters
Accept data from the URL and request body with type validation.
- Beginner
- 15 min read
- 3 objectives
Before this lessonLesson 1: Introduction and First Endpoint
What you will learn
- Use path and query parameters
- Model a body with Pydantic
- Return validation errors
Real endpoints take input. FastAPI reads it from three places and validates it using your type hints: the URL path, the query string and the request body.
Path parameters
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id}Requesting /users/42 gives you the integer 42. Requesting /users/abc automatically returns an HTTP 422 error explaining that the value is not a valid integer. You wrote no validation code.
Query parameters
Function parameters that are not in the path become query parameters. Give them defaults to make them optional.
from fastapi import Query
@app.get("/search")
def search(q: str, limit: int = 10, page: int = Query(1, ge=1)):
return {"q": q, "limit": limit, "page": page}
# GET /search?q=python&limit=5Query(1, ge=1) adds a rule: the value must be greater than or equal to 1. Similar options: le, min_length, max_length, pattern.
Request body with Pydantic
For JSON bodies, describe the shape with a Pydantic model. FastAPI parses the JSON, validates every field and gives you a typed object.
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(min_length=1, max_length=50)
price: float = Field(gt=0)
tags: list[str] = []
in_stock: bool = True
@app.post("/items")
def create_item(item: Item):
return {"created": item.name, "total_with_tax": round(item.price * 1.2, 2)}curl -X POST http://127.0.0.1:8000/items \
-H "Content-Type: application/json" \
-d '{"name": "Pen", "price": 1.5}'{"created":"Pen","total_with_tax":1.8}Validation errors
Send {"name": "", "price": -1} and FastAPI replies with status 422 and a list showing exactly which fields failed and why. Clients get clear, consistent errors for free.
Mixing all three
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item, notify: bool = False):
return {"id": item_id, "item": item, "notify": notify}FastAPI infers each source: item_id is in the path, item is a body model, and notify is a query parameter.
# Write your solution here
