Skip to main content

Common Parameter Metadata

In FastAPI, all request parameters—whether they originate from the query string, path, headers, or cookies—share a common foundation. This foundation is implemented via the Param class in fastapi/params.py, which extends Pydantic's FieldInfo. By centralizing validation logic and OpenAPI metadata in this base class, FastAPI ensures a consistent developer experience across different data sources.

The Param Base Class

The Param class serves as the abstract blueprint for specific parameter types like Query, Path, Header, and Cookie. It inherits from Pydantic's FieldInfo, which allows it to leverage Pydantic's robust validation engine while adding web-specific metadata required for OpenAPI schema generation.

Every Param instance includes an in_ attribute of type ParamTypes, which is an enumeration defining the parameter's location:

class ParamTypes(Enum):
query = "query"
header = "header"
path = "path"
cookie = "cookie"

When you use a subclass like Query or Path, FastAPI automatically sets this in_ attribute, which later informs the OpenAPI utility functions (found in fastapi/openapi/utils.py) where to place the parameter in the generated documentation.

Shared Validation Logic

Because Param inherits from FieldInfo, it exposes a wide array of validation parameters that apply to almost all request data. These are passed through to the underlying Pydantic model during request validation:

  • Numeric Validation: Attributes like gt (greater than), ge (greater than or equal), lt (less than), and le (less than or equal) allow for strict range checking on numeric inputs.
  • String Validation: min_length, max_length, and pattern (which replaces the deprecated regex) provide constraints for string-based parameters.
  • Metadata: title and description are used to enrich the generated OpenAPI documentation.

The __init__ method of Param handles the consolidation of these attributes, ensuring that even if they are passed as extra keyword arguments, they are correctly mapped to the internal Pydantic structure:

# From fastapi/params.py
class Param(FieldInfo):
def __init__(
self,
default: Any = Undefined,
*,
# ... validation and metadata arguments
gt: float | None = None,
le: float | None = None,
pattern: str | None = None,
# ...
):
# ... logic to handle deprecations and aliases
super().__init__(**use_kwargs)

OpenAPI Documentation Attributes

FastAPI uses the Param class to store metadata that doesn't affect validation but is critical for documentation.

Examples and Deprecation

The implementation reflects changes in the OpenAPI specification. For instance, the example attribute is deprecated in favor of examples (a list), aligning with OpenAPI 3.1.0:

if example is not _Unset:
warnings.warn(
"`example` has been deprecated, please use `examples` instead",
category=FastAPIDeprecationWarning,
stacklevel=4,
)

Schema Visibility

The include_in_schema boolean allows developers to hide specific parameters from the public API documentation without removing them from the functional logic of the endpoint.

Alias Handling and Priority

One of the most powerful features of the Param class is its sophisticated handling of aliases. This is essential for web development where internal Python variable names (which cannot contain hyphens) must map to external wire formats (like Content-Type headers).

The Param class automatically synchronizes alias, validation_alias, and serialization_alias if they are not explicitly provided:

if serialization_alias in (_Unset, None) and isinstance(alias, str):
serialization_alias = alias
if validation_alias in (_Unset, None):
validation_alias = alias

This ensures that if you define Query(alias="item-id"), FastAPI knows to look for item-id in the request and also use item-id when generating the schema or serializing the response.

Implementation Nuances in Subclasses

While Param provides the shared logic, subclasses introduce specific constraints and behaviors:

  • Path Parameters: The Path class explicitly forbids default values. Since a path parameter is a mandatory part of the URL, providing a default would be logically inconsistent. This is enforced by an assertion in Path.__init__:
    assert default is ..., "Path parameters cannot have a default value"
  • Header Parameters: The Header class includes a convert_underscores attribute (defaulting to True). This automatically transforms Pythonic underscores into hyphens (e.g., user_agent becomes User-Agent), which is the standard convention for HTTP headers.

By centralizing these behaviors in Param, FastAPI maintains a dry (Don't Repeat Yourself) architecture where the core logic of "a piece of data from a request" is separated from the specific "where" of that data.