Query parameters are the key-value pairs after the ? in a URL (/items?skip=0&limit=10). Any function parameter that is not part of the path is automatically treated as a query parameter.
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}
@app.get("/search/")
def search(q: Optional[str] = None):
return {"q": q}
skip: int = 0: optional with default 0 — /items/ works fine.q: Optional[str] = None: optional, no default value.name: str (no default): required — missing it returns 422.@app.get("/products/")
def list_products(active: bool = True):
return {"active": active}
FastAPI accepts active=true, active=1, active=yes, active=on as True, and false, 0, no, off as False.
from typing import List
@app.get("/tags/")
def filter_tags(tags: List[str] = []):
return {"tags": tags}
A URL like /tags/?tags=python&tags=api produces tags=["python", "api"].
from fastapi import FastAPI, Query
@app.get("/items/")
def read_items(
q: str | None = Query(default=None, min_length=3, max_length=50, pattern="^fixedquery"),
page: int = Query(default=1, gt=0),
):
return {"q": q, "page": page}
Query() adds metadata (title, description, deprecated) and constraints (min_length, pattern, gt/ge) that appear both in validation errors and in the OpenAPI docs.
A: By name. If the parameter name appears in the path template ({item_id}), it is a path parameter; otherwise it is read from the query string. Use Path() or Query() to be explicit.
A: The request fails with 422 and a message like {"loc": ["query", "name"], "msg": "Field required"}. The client knows exactly what to fix.
Optional[str] = None the same as str = None?A: Practically both make the parameter optional in FastAPI, but Optional[str] = None (or str | None = None in Python 3.10+) is the correct typing; a plain str = None lies to the type checker and modern FastAPI versions may reject it.
Query parameters handle filtering, pagination and search options. Declaring them with types and Query() constraints gives you automatic conversion, validation, sensible 422 errors and self-documenting endpoints.