FastAPI Query Parameter Validation
FastAPI allows you to declare additional validation rules and metadata for query parameters, such as string length limits, regex matching, etc. ThroughQueryandAnnotated, you can enhance parameter validation without changing the function logic.
Basic validation
The following example is query parametersqAdd maximum length limit:
Example
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
# Use Annotated + Query to add validation
q: Annotated[str | None, Query(max_length=50)] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Code explanation:
| Part | Description |
|---|---|
Annotated[str | None, ...] | Type annotations, meaningqCan be a string or None |
Query(max_length=50) | Validation rules,qThe maximum length is 50 characters |
= None | Default value, making the parameter optional |
FastAPI recommends using
AnnotatedDeclare validation in a way, rather than usingQueryas the default value. BecauseAnnotatedIn this approach, the function's default value is the real default value, which is more intuitive in Python and better supported by editors and type checking tools.
Adding more validation
You can add multiple validation rules simultaneously:
Example
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
# Also limit minimum length, maximum length, and regular expression
q: Annotated[str | None, Query(min_length=3, max_length=50, pattern="^fixedquery$")] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
String validation parameters:
| Parameter | Type | Description |
|---|---|---|
min_length | int | Minimum length |
max_length | int | Maximum length |
pattern | str | Regular expression matching |
Regular expression^fixedquery$Meaning:
^-- Must start with the following charactersfixedquery-- Value must exactly equalfixedquery$-- End here; no other characters may follow.
Validation with default values
You can set both a default value and validation rules for a query parameter:
Example
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
# The default value is "fixedquery", and the minimum length is 3
q: Annotated[str, Query(min_length=3)] = "fixedquery",
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Default value of any type (including non-
Nonevalue) will make the parameter optional. Without a default value and withoutQuery(default=...)parameters are required.
Required parameter
UsageQuery, if you don't declare a default value, the parameter is required:
Example
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
# No value = None, so q is a required parameter.
q: Annotated[str, Query(min_length=3)],
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
results.update({"q": q})
return results
Required but can be None
Sometimes you need the client to pass a value, but the value can beNone:
Example
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
# The client must provide the q parameter, but the value can be None
q: Annotated[str | None, Query(min_length=3)],
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Query parameter list / multiple values
UsageQueryYou can declare query parameters that receive multiple values:
Example
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
# q can appear multiple times in the URL, and the values will be collected as a list
q: Annotated[list[str] | None, Query()] = None,
):
query_items = {"q": q}
return query_items
Visithttp://127.0.0.1:8000/items/?q=foo&q=bar, returns:
{"q": ["foo", "bar"]}
To declare the type as
listquery parameters, must explicitly useQuery(), otherwise FastAPI will interpret it as the request body.
Declare metadata
QueryIt also supports adding metadata to parameters; this information will appear in the API documentation:
Example
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
q: Annotated[str | None, Query(
title="query string", # Parameter Title
description="Query string used to filter products", # Parameter Description
min_length=3,
max_length=50,
alias="item-query", # Alias for parameter name in URL
deprecated=True, # Mark as deprecated
)] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
Metadata parameter description:
| Parameter | Description | Use Case |
|---|---|---|
alias | Alias for parameter name in URL | Parameter name contains hyphen (e.g.item-query), when it is not a valid Python variable name |
title | Parameter title | Display parameter title in documentation |
description | Parameter description | Display detailed description of parameter in documentation |
deprecated | Marked as deprecated | The parameter can still be used, but it will be marked as "deprecated" in the documentation. |
include_in_schema | Whether to appear in API documentation | Set asFalseHideable parameters |
Exclude parameters from OpenAPI
If a query parameter should not appear in the API documentation:
Example
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(
# hidden_query will not appear in the API documentation, but it can still be used
hidden_query: Annotated[str | None, Query(include_in_schema=False)] = None,
):
if hidden_query:
return {"hidden_query": hidden_query}
return {"items": [{"item_id": "Foo"}]}
Summary
Key points of query parameter validation:
- Usage
Annotated+QueryDeclaring validation rules (recommended approach) - String validation:
min_length、max_length、pattern - No default value = required parameter; with default value = optional parameter
aliasUsed for parameter names in URLs that are not valid Python variable names.deprecated=TrueMarking deprecated parameters- Usage
list[str]Receive multiple query parameters with the same name