Learn / Frameworks / FastAPI / Path, Query and Body Parameters

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=5

Query(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}'
Output
{"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
Up next · Lesson 3Models, Responses and ErrorsResponse models, status codes and raising HTTP errors.