Skip to main content

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:

  1. Validate that the string length is between 3 and 50 characters.
  2. Generate a 422 Unprocessable Entity error if the validation fails.
  3. 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 deprecated regex), gt, ge, etc.
  • Metadata: Use title, description, examples, and deprecated.
  • URL Mapping: Use alias to support characters like hyphens.
  • Visibility: Use include_in_schema=False to hide a parameter from the documentation.

Next, you might want to explore Path Parameters to handle dynamic segments in your URL paths.