FastAPI Query Parameters
Query parameters are optional (or required) pieces of information you attach to a URL after a question mark. They let callers filter, sort, search, or paginate data without changing the route path itself.
What a Query Parameter Looks Like in a URL
https://example.com/products?category=shoes&sort=price&page=2
│
└── query string starts here
Key-value pairs:
category = shoes
sort = price
page = 2
Each pair is separated by &. The first pair starts after the ?.
Declaring Query Parameters in FastAPI
Any function parameter that does NOT appear in the path string becomes a query parameter automatically:
@app.get("/products")
def get_products(category: str, page: int):
return {"category": category, "page": page}
Path string: "/products" ← no {category} or {page} here
Function args: category, page ← FastAPI reads these from the URL query string
Call it like this:
GET /products?category=shoes&page=2
Returns: {"category": "shoes", "page": 2}
Optional Query Parameters
Make a parameter optional by giving it a default value:
@app.get("/products")
def get_products(category: str = "all", page: int = 1):
return {"category": category, "page": page}
GET /products
→ {"category": "all", "page": 1} ← defaults used
GET /products?category=shoes
→ {"category": "shoes", "page": 1} ← page still uses default
GET /products?category=shoes&page=3
→ {"category": "shoes", "page": 3} ← both overridden
Optional Parameters That Can Be None
Use Optional from Python's typing module when a parameter might not be sent at all:
from typing import Optional
@app.get("/search")
def search(query: Optional[str] = None):
if query is None:
return {"results": "Show everything"}
return {"results": f"Searching for: {query}"}
Path Parameter vs Query Parameter — Side by Side
Route: @app.get("/users/{user_id}")
Path Param Query Param
Example URL: /users/42 /users?id=42
Position: Inside the path After the ?
Required?: Always required Can be optional
Best for: Identifying Filtering,
one resource sorting, searching
Combining Path and Query Parameters
A single route can use both at the same time:
@app.get("/shops/{shop_id}/items")
def get_shop_items(shop_id: int, in_stock: bool = True, limit: int = 10):
return {
"shop": shop_id,
"in_stock": in_stock,
"limit": limit
}
GET /shops/7/items?in_stock=false&limit=5 → shop_id = 7 (from path) → in_stock = False (from query) → limit = 5 (from query)
Boolean Query Parameters
FastAPI is smart about booleans. These all count as True:
?active=true ?active=1 ?active=yes ?active=on
And these all count as False:
?active=false ?active=0 ?active=no ?active=off
Adding Validation with Query
Import Query from FastAPI to add length or value limits:
from fastapi import Query
@app.get("/search")
def search(q: str = Query(min_length=3, max_length=50)):
return {"query": q}
GET /search?q=ab → Error: min length is 3 GET /search?q=shoes → OK
Key Points
- Query parameters appear after the
?in a URL askey=valuepairs. - Any function argument not in the path string is automatically a query parameter.
- Give a default value to make a parameter optional.
- Use
Optional[str] = Nonewhen the parameter may be completely absent. - Use
Query()to add validation like minimum or maximum length.
