Query Parameters

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.

Required, Optional and Default Values

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}

Booleans Are Converted Automatically

@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.

Multiple Values for the Same Key

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"].

Validation with Query()

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.

Quick Questions and Answers

Q: How does FastAPI distinguish path parameters from query parameters?

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.

Q: What happens if a required query parameter is missing?

A: The request fails with 422 and a message like {"loc": ["query", "name"], "msg": "Field required"}. The client knows exactly what to fix.

Q: Is 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.

Conclusion

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.