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 typing import Annotated
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:

PartDescription
Annotated[str | None, ...]Type annotations, meaningqCan be a string or None
Query(max_length=50)Validation rules,qThe maximum length is 50 characters
= NoneDefault value, making the parameter optional

FastAPI recommends usingAnnotatedDeclare 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 typing import Annotated
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:

ParameterTypeDescription
min_lengthintMinimum length
max_lengthintMaximum length
patternstrRegular expression matching

Regular expression^fixedquery$Meaning:

  • ^-- Must start with the following characters
  • fixedquery-- 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 typing import Annotated
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 typing import Annotated
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 typing import Annotated
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 typing import Annotated
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 aslistquery 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 typing import Annotated
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:

ParameterDescriptionUse Case
aliasAlias for parameter name in URLParameter name contains hyphen (e.g.item-query), when it is not a valid Python variable name
titleParameter titleDisplay parameter title in documentation
descriptionParameter descriptionDisplay detailed description of parameter in documentation
deprecatedMarked as deprecatedThe parameter can still be used, but it will be marked as "deprecated" in the documentation.
include_in_schemaWhether to appear in API documentationSet asFalseHideable parameters

Exclude parameters from OpenAPI

If a query parameter should not appear in the API documentation:

Example

from typing import Annotated
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:

  • UsageAnnotated + 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
  • Usagelist[str]Receive multiple query parameters with the same name
other extensions