Query Parameters
When you define a function parameter in a path operation that is not part of the path, FastAPI automatically interprets it as a "query" parameter. These are the key-value pairs that appear after the ? in a URL, such as ?limit=10&offset=0.
In this tutorial, you will build a search interface for an items collection that uses the Query class to validate inputs, define aliases for URL-unfriendly names, and handle multiple values for a single parameter.
Prerequisites
To follow this guide, you need FastAPI installed:
pip install fastapi
Step 1: Define Basic Query Parameters
In FastAPI, any function argument that is a primary type (like str, int, bool) and is not part of the path is treated as a query parameter.
Create a file named main.py:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/")
async def read_items(q: str | None = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
In this example, q is an optional query parameter because it has a default value of None. If you visit /items/?q=baz, the value of q will be "baz". If you visit /items/, q will be None.
Step 2: Add Validations with the Query Class
To add constraints or metadata to your query parameters, use the Query class from fastapi.params. This class inherits from Param and explicitly sets the parameter location to ParamTypes.query.
Update your read_items function to use Annotated and Query:
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(max_length=50, min_length=3)] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
By using Query(max_length=50, min_length=3), you are telling FastAPI to:
- Validate that the string length is between 3 and 50 characters.
- Generate a
422 Unprocessable Entityerror if the validation fails. - Document these constraints in the generated OpenAPI schema.
Step 3: Use Aliases for Special Characters
Sometimes you need a query parameter name that is not a valid Python variable name, such as item-query. You can handle this using the alias parameter in Query.
@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(alias="item-query")] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Now, a request to /items/?item-query=fixed will map the value "fixed" to your function argument q.
Step 4: Accept Multiple Values
If you want to allow a query parameter to appear multiple times in the URL (e.g., /items/?q=foo&q=bar), declare the type as a list.
@app.get("/items/")
async def read_items(q: Annotated[list[str] | None, Query()] = None):
query_items = {"q": q}
return query_items
When you call this with /items/?q=foo&q=bar, the value of q inside your function will be the Python list ["foo", "bar"].
Step 5: Add Metadata for Documentation
You can provide additional information that will appear in the interactive API documentation (Swagger UI) using title, description, and deprecated.
@app.get("/items/")
async def read_items(
q: Annotated[
str | None,
Query(
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
deprecated=True,
),
] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Complete Example
Here is the final code combining these concepts:
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[
list[str] | None,
Query(
alias="item-query",
title="Search Query",
description="Search for multiple items using the 'item-query' parameter",
min_length=3,
max_length=50,
pattern="^[a-zA-Z0-9]+$",
),
] = None,
):
"""
Search for items with validation, aliases, and multiple value support.
"""
return {"query_received": q}
Summary of Query Features
- Validation: Use
min_length,max_length,pattern(replaces the deprecatedregex),gt,ge, etc. - Metadata: Use
title,description,examples, anddeprecated. - URL Mapping: Use
aliasto support characters like hyphens. - Visibility: Use
include_in_schema=Falseto hide a parameter from the documentation.
Next, you might want to explore Path Parameters to handle dynamic segments in your URL paths.