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.