FastAPI Path Parameters and Query Parameters
/items/{id}). Query parameters are any function arguments not found in the path string. FastAPI uses Python type hints to automatically validate, convert, and document these parameters. If a type mismatch occurs, FastAPI immediately returns a structured 422 Unprocessable Entity error, protecting your logic from bad data.
Path Parameters: Resource Identification
Use path parameters to identify a specific resource. FastAPI supports 'Path Converters' like :path, which allows a parameter to match any path, including slashes—perfect for building file explorers or proxy services.
from fastapi import FastAPI, Path from typing import Annotated app = FastAPI() @app.get('/forge/users/{user_id}') def get_user_by_id( # Use Annotated and Path() for advanced metadata/validation user_id: Annotated[int, Path(title="The ID of the user to get", ge=1)] ): return {"user_id": user_id, "context": "internal_forge_registry"} # Advanced: The ':path' converter for nested structures @app.get('/forge/assets/{file_path:path}') def get_asset_stream(file_path: str): return {"requested_path": file_path} # GET /forge/assets/images/branding/logo.png # -> {'requested_path': 'images/branding/logo.png'}
Query Parameters: Filtering and Pagination
Query parameters are the standard for non-hierarchical data. By providing a default value, you make the parameter optional. We recommend using Optional (or the | None syntax in Python 3.10+) to keep your API's intent explicit for both developers and the Pydantic validator.
from fastapi import FastAPI from typing import Optional app = FastAPI() @app.get('/forge/search') def list_artifacts( query: str, # Required (no default) page: int = 1, # Optional (default: 1) tag: Optional[str] = None # Optional (default: None) ): return { 'search_term': query, 'pagination': {'page': page}, 'filter': tag } # GET /forge/search?query=api&page=2 # -> {'search_term': 'api', 'pagination': {'page': 2}, 'filter': None}
Complex Validation with Query()
When simple type hints aren't enough, use the Query class to enforce business rules like string length, numeric ranges (greater than/less than), or even regular expression patterns.
from fastapi import FastAPI, Query from typing import Annotated app = FastAPI() @app.get('/forge/audit-logs') def get_logs( # min_length: 3, max_length: 10, must match 'FORGE-' prefix service_id: Annotated[str, Query(min_length=3, pattern="^FORGE-.*$")], # limit must be between 1 and 100 limit: int = Query(default=20, ge=1, le=100) ): return {'service': service_id, 'limit': limit} # GET /forge/audit-logs?service_id=FORGE-AUTH&limit=50 -> Valid # GET /forge/audit-logs?service_id=EXTERNAL -> 422 (Regex fail)
🎯 Key Takeaways
- Hierarchical data (identifying a specific object) belongs in Path parameters; non-hierarchical data (filtering/sorting) belongs in Query parameters.
- Type hints drive the entire ecosystem: validation, conversion, and documentation (Swagger/ReDoc).
- Default values dictate requirement: An argument without a default is a required parameter.
- FastAPI supports multi-value query parameters using
list[str]type hints (e.g.,?tag=python&tag=web). - Annotated is the modern way to combine type hints with FastAPI-specific validation logic without breaking IDE autocompletion.
Interview Questions on This Topic
- QHow does FastAPI's internal resolution logic determine if a function argument is a Body, Path, or Query parameter?
- QWhy is the `Annotated` pattern preferred over assigning `Query()` or `Path()` directly as a default value in modern FastAPI versions?
- QExplain the 'Path Converter' concept. How would you capture a full file path (including slashes) as a single parameter?
- QScenario: You have a query parameter `tags` that should accept a list of strings. How do you define this such that it appears correctly in the generated OpenAPI documentation?
- QIn a high-performance system, how does FastAPI's use of Pydantic for parameter validation impact latency compared to raw dictionary access?
Frequently Asked Questions
What is the difference between a path parameter and a query parameter?
Path parameters are essential parts of the URL (e.g., /users/123) and are used to locate a specific resource. Query parameters appear after the '?' (e.g., /users?role=admin) and are used to modify the representation of that resource, such as filtering, sorting, or paginating a list.
How does FastAPI handle boolean query parameters?
FastAPI is quite flexible with booleans. It interprets 'true', '1', 'on', 'yes', and 'True' as True. Similarly, 'false', '0', 'off', 'no', and 'False' are mapped to False. This ensures that your API is compatible with various frontend libraries and command-line tools.
Can a query parameter be a list?
Yes. By defining a parameter as list[str] or List[int], FastAPI will look for multiple instances of that key in the URL. For example, ?id=1&id=2&id=3 will be injected into your function as the Python list [1, 2, 3].
What is the 422 Unprocessable Entity error in FastAPI?
A 422 error occurs when the client's request is syntactically correct (valid HTTP) but contains semantically invalid data. For instance, passing 'abc' to a parameter typed as int. FastAPI automatically generates a detailed JSON response body showing exactly which field failed and why, saving you from writing manual validation logic.
Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.