404 Not Found

404 Not Found


nginx

Path Parameters and Query Parameters — Precision Routing Design

Routing design is like urban road planning—path parameters are like street addresses (precise location), and query parameters are like filter criteria (narrowing down the scope); only when the two work together can you quickly find your destination.

1. What You'll Learn


2. Alice's True Story

(1) Pain Point: Confusing Product Query API Parameters

Alice's PriceTracker needs to support multiple query methods: exact queries by product ID, filtering by category and price range, and paginated browsing by sort order. Bob passed category=electronics&min_price=10&max_price=999 from the front end, but Alice's Flask code manually parses each parameter. Type conversions are prone to errors, and there are no validations for negative prices or invalid sort fields, leading to frequent production incidents.

(2) Solutions for Parameter Validation in FastAPI

FastAPI uses type hints to automatically parse and validate parameters. Path() and Query() provide declarative constraints, and invalid parameters automatically trigger a 422 error.

PYTHON
from fastapi import FastAPI, Path, Query

app = FastAPI()

@app.get("/products/{product_id}")
async def get_product(
    product_id: int = Path(gt=0, description="Product ID must be positive"),
    category: str | None = Query(None, max_length=50),
):
    return {"product_id": product_id, "category": category}

(3) Revenue

The parameter validation code has been reduced from 30 lines to 3 lines, and 422 error responses now automatically include specific details about the validation failure, allowing Bob to immediately identify which parameter is incorrect. The API documentation also automatically displays all constraints.


3. Detailed Explanation of Path Parameters

(1) Basic Path Parameters

Path parameters are part of the URL path and are defined using the {param} syntax; FastAPI automatically converts them based on type hints.

100%
sequenceDiagram
    participant Client
    participant Router as FastAPI Router
    participant Converter as Type Converter
    participant Validator as Path Validator
    participant Handler as View Function

    Client->>Router: GET /products/42
    Router->>Converter: Extract "42" from path
    Converter->>Converter: int("42") → 42
    Converter->>Validator: product_id=42 (int)
    Validator->>Validator: Check gt=0 → 42 > 0 ✓
    Validator->>Handler: get_product(product_id=42)
    Handler-->>Client: {"product_id": 42}
Path Parameter Type URL Example Python Type Automatic Conversion
Integer /products/42 int "42"42
Floating-point numbers /prices/9.99 float "9.99"9.99
String /categories/electronics str As-is
Path /files/src/main.py Path String containing /

(1) ▶ Example: Base Path Parameters and Type Conversion

PYTHON
from fastapi import FastAPI

app = FastAPI()

@app.get("/products/{product_id}")
async def get_product(product_id: int):
    # FastAPI auto-converts "42" to int(42)
    # If user sends /products/abc → 422 error
    return {"product_id": product_id, "type": str(type(product_id))}

Output:

TEXT
INFO:     127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK

Output (/products/42):

TEXT
{"product_id": 42, "type": "<class 'int'>"}

(2) Path() Constraint Validation

Path() Add constraints such as numerical ranges and string lengths to path parameters; these are automatically reflected in the OpenAPI documentation.

Constraint Parameter Applicable Type Meaning
gt int/float greater than (>)
ge int/float greater than or equal to (>=)
lt int/float less than (<)
le int/float less than or equal to (<=)
min_length str Minimum Length
max_length str Maximum length
pattern str Regular expression match
description All OpenAPI Description

(2) ▶ Example: Path() Numeric Constraints

PYTHON
from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/products/{product_id}")
async def get_product(
    product_id: int = Path(
        gt=0,
        le=1000000,
        description="Product ID: positive integer, max 1 million",
    ),
):
    return {"product_id": product_id}

Output:

TEXT
INFO:     127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK

Output (/products/-1 returns 422):

TEXT
{
  "detail": [
    {
      "loc": ["path", "product_id"],
      "msg": "Input should be greater than 0",
      "type": "greater_than"
    }
  ]
}

4. Detailed Explanation of Query Parameters

(1) Basic Query Parameters

Query parameters are the key-value pairs that follow ? in the URL. They are declared as function parameters, and parameters with default values are optional.

Query Parameter Type Declaration Method Required
Required category: str Yes
Optional (default) category: str = "all" No
Optional (None) `category: str None = None`

(1) ▶ Example: Query Parameter Basics

PYTHON
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/prices")
async def search_prices(
    category: str | None = Query(None, max_length=50, description="Product category"),
    min_price: float = Query(0.0, ge=0, description="Minimum price in USD"),
    max_price: float = Query(999999.0, le=999999, description="Maximum price in USD"),
):
    return {
        "category": category,
        "price_range": f"${min_price} - ${max_price}",
    }

Output:

TEXT
INFO:     127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK

Output (/prices?category=electronics&min_price=10&max_price=500):

TEXT
{"category": "electronics", "price_range": "$10.0 - $500.0"}

(2) Query() Advanced Options

Option Function Example
alias Parameter aliases (e.g., camel case to snake case) Query(alias="minPrice")
deprecated Mark as Obsolete Query(deprecated=True)
title OpenAPI Title Query(title="Category Filter")
description OpenAPI Description Query(description="...")
examples Sample Value Query(examples=["electronics"])

(2) ▶ Example: alias and deprecated

PYTHON
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/products")
async def list_products(
    sort_by: str = Query(
        "name",
        alias="sortBy",
        description="Sort field: name, price, created_at",
    ),
    old_filter: str | None = Query(
        None,
        deprecated=True,
        description="Use sort_by instead",
    ),
):
    return {"sort_by": sort_by}

Output:

TEXT
# Function defined successfully

5. Enumeration Parameters

(1) Limiting the Possible Values in a String Enumeration

When a parameter can only take a fixed set of values, use the Enum constraint, and FastAPI will automatically display a drop-down menu in the documentation.

(1) ▶ Example: Enumerating Path Parameters

PYTHON
from enum import Enum
from fastapi import FastAPI

class Category(str, Enum):
    electronics = "electronics"
    clothing = "clothing"
    food = "food"
    books = "books"

app = FastAPI()

@app.get("/categories/{category}")
async def get_category(category: Category):
    return {
        "category": category,
        "value": category.value,
        "label": category.name,
    }

Output:

TEXT
INFO:     127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK

Output (/categories/electronics):

TEXT
{"category": "electronics", "value": "electronics", "label": "electronics"}

(2) ▶ Example: Enumerating Query Parameters and Sorting

PYTHON
from enum import Enum
from fastapi import FastAPI, Query

class SortOrder(str, Enum):
    asc = "asc"
    desc = "desc"

app = FastAPI()

@app.get("/products")
async def list_products(
    sort_order: SortOrder = Query(SortOrder.asc),
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
):
    return {
        "sort": sort_order.value,
        "limit": limit,
        "offset": offset,
    }

Output:

TEXT
# Function defined successfully

6. Combining Multiple Parameters and Pitfalls

(1) Rules for the Order of Parameter Declarations

FastAPI's rules for determining parameter types: Any {param} in the path is a path parameter; otherwise, it is a query parameter (parameters with type annotations are required, and those with default values are optional).

Order Parameter Type Criteria
1 Path Parameter URL contains {param}
2 Query parameters (required) No default value; not included in the path
3 Query parameters (optional) Has a default value or None
PYTHON
from fastapi import FastAPI, Path, Query
from enum import Enum

class Category(str, Enum):
    electronics = "electronics"
    clothing = "clothing"
    food = "food"

app = FastAPI()

@app.get("/products/{product_id}/prices")
async def get_product_prices(
    product_id: int = Path(gt=0, description="Product ID"),
    category: Category | None = Query(None, description="Filter by category"),
    min_price: float = Query(0.0, ge=0, description="Min price in USD"),
    max_price: float = Query(99999.0, ge=0, description="Max price in USD"),
    sort: str = Query("date", pattern="^(date|price)$"),
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
):
    return {
        "product_id": product_id,
        "category": category,
        "price_range": [min_price, max_price],
        "sort": sort,
        "pagination": {"limit": limit, "offset": offset},
    }

Output:

TEXT
# Function defined successfully

(2) Common Pitfalls

Pitfalls Incorrect Syntax Correct Syntax
Path parameter is optional product_id: int = None Path parameter is required
Default value conflicts with Query limit: int = 20, Query(ge=1) limit: int = Query(20, ge=1)
Optional parameters: None category: str = None `category: str
Enumerations Do Not Use the str Base Class class Cat(Enum): class Cat(str, Enum):

7. Comprehensive Example

Path parameters, query parameters, and enum constraints are the foundation for building flexible APIs. Below, we combine path constraints, query pagination, and enum filtering.

PYTHON
from fastapi import FastAPI, Path, Query
from enum import Enum

app = FastAPI()

class SortOrder(str, Enum):
    asc = "asc"
    desc = "desc"

PRODUCTS = [{"id": i, "name": f"Product-{i}", "price": i * 10.0} for i in range(1, 101)]

@app.get("/products/{product_id}")
async def get_product(
    product_id: int = Path(gt=0, description="Product ID"),
    sort: SortOrder = Query(SortOrder.asc),
    limit: int = Query(10, ge=1, le=100),
    offset: int = Query(0, ge=0),
):
    return {
        "product_id": product_id,
        "sort": sort.value,
        "limit": limit,
        "offset": offset,
    }

Output:

TEXT
GET /products/5?sort=desc&limit=20&offset=10 → {"product_id":5,"sort":"desc","limit":20,"offset":10}
GET /products/0 → 422 Validation Error (product_id must be > 0)

❓ FAQ

Q Can path parameters and query parameters have the same name?
A No. FastAPI will throw an error because it cannot distinguish between parameters with the same name.
Q How do I make a query parameter required?
A Simply do not provide a default value. For example, category: str is required, while category: str = "all" is optional. You can also explicitly mark a parameter as required using Query(...).
Q Could overly detailed error messages (such as error 422) expose sensitive information?
A Detailed error messages are helpful during development. In a production environment, you can use a custom exception handler to simplify the response and return only "Parameter validation failed."
Q Can Enum parameters accept lowercase letters?
A By default, they are case-sensitive. If you want them to be case-insensitive, you need to define a custom validator or use lowercase letters in the Enum values.
Q What is the difference between "gt" and "ge" in Path()?
A gt=0 means the value must be > 0 (excluding 0), while ge=0 means >= 0 (including 0). ID-type parameters generally use gt=0, while price-type parameters use ge=0.
Q How do I limit the length of query parameters?
A Use Query(max_length=N) to limit the length of strings, and Query(ge=N, le=M) to limit numerical ranges.

📖 Summary


📝 Exercises

  1. Basic Problem (Difficulty ⭐): Create a GET endpoint /items/{item_id} that takes item_id (a positive integer) as input and returns {"item_id": item_id}. Hint: item_id: int = Path(gt=0)
  2. Advanced Problem (Difficulty ⭐⭐): Create the /products query endpoint for PriceTracker, which supports three query parameters: category (optional string, up to 50 characters), min_price (≥0), and max_price (≤999999). Hint: Query(None, max_length=50)
  3. Challenge Question (Difficulty: ⭐⭐⭐): Create a /products/{product_id}/prices endpoint and, using path parameters (product_id > 0), enumeration query parameters (SortOrder: asc/desc), and pagination parameters (limit 1-100, offset ≥ 0), verify that invalid input returns a 422 error. Hint: Define SortOrder(str, Enum) and multiple Query() endpoints.

---|

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏