Home/Learn/FastAPI/Path & Query Parameters — Typed and Validated

Path & Query Parameters — Typed and Validated

Beginner
Fundamentals

Function parameters that appear in the path are path params; the rest become query params. Type hints convert and validate both; Path() and Query() add constraints like ge=1 or max_length=50.

Overview

FastAPI reads your function signature and sorts parameters automatically: names present in the route path ("/orders/{order_id}") bind from the URL path, everything else binds from the query string, with defaults making them optional. Type hints do conversion and validation — order_id: int turns "42" into 42 and rejects "abc" with a 422. For real constraints you wrap defaults in Path() and Query(): numeric bounds (ge, le), string rules (min_length, max_length, pattern), and metadata that flows straight into the docs. Enums restrict a param to fixed choices, and list[str] captures repeated query keys — the whole request-parsing layer of a typical Flask app, gone.

Path Params + Query Params from One Signature

In the signature: path names must match the route placeholders; parameters with defaults become optional query params; bool converts "true"/"1"/"yes" intelligently. Order in the URL never matters for query params.

The signature is the parser: path vs query decided by name + default
from fastapi import FastAPI

app = FastAPI()

# /trains/12345/coaches/S4?berth=upper&confirmed=true
@app.get("/trains/{train_no}/coaches/{coach}")
def coach_status(
    train_no: int,               # path — converted from "12345"
    coach: str,                  # path
    berth: str = "any",          # query — optional (has default)
    confirmed: bool = False,     # query — "true"/"True"/"1"/"yes" all work
):
    return {"train": train_no, "coach": coach, "berth": berth, "confirmed": confirmed}

# Optional query param that may be absent entirely:
@app.get("/students")
def search(branch: str | None = None, limit: int = 10):
    q = {"limit": limit}
    if branch:
        q["branch"] = branch
    return q

# Repeated query keys → list:  /tags?tag=python&tag=fastapi
@app.get("/tags")
def tags(tag: list[str] = []):
    return {"tags": tag}                 # ["python", "fastapi"]

# Route order matters — fixed paths BEFORE parameterised ones:
@app.get("/students/me")                 # must come first...
def current_student(): return {"me": True}

@app.get("/students/{student_id}")       # ...or this would capture "me"
def one_student(student_id: int): return {"id": student_id}

Constraints with Path() and Query(), Choices with Enum

Path() and Query() add validation rules and documentation. ge/le bound numbers; min_length/max_length/pattern police strings. An Enum parameter gives a dropdown in /docs and a 422 for anything else.

ge/le, length, pattern, Enum — declarative guard rails
from enum import Enum
from fastapi import FastAPI, Path, Query

app = FastAPI()

class Branch(str, Enum):        # str + Enum → JSON-friendly choices
    cs = "cs"
    it = "it"
    mech = "mech"

# /colleges/pune/students?branch=cs&min_cgpa=7.5&q=asha
@app.get("/colleges/{city}/students")
def college_students(
    city: str = Path(min_length=2, max_length=30, description="City name"),
    branch: Branch | None = None,                    # only cs/it/mech accepted
    min_cgpa: float = Query(default=0.0, ge=0.0, le=10.0),
    q: str | None = Query(default=None, min_length=2, pattern="^[a-zA-Z ]+$"),
    page: int = Query(default=1, ge=1),
    size: int = Query(default=20, ge=1, le=100),     # cap page size!
):
    return {"city": city, "branch": branch, "min_cgpa": min_cgpa,
            "q": q, "page": page, "size": size}

# min_cgpa=11  → 422 "Input should be less than or equal to 10"
# branch=civil → 422 "Input should be 'cs', 'it' or 'mech'"
# Every rule above also appears in /docs automatically.

Key Points to Remember

  • 1In the path → path param; has a default → query param; the signature decides
  • 2Type hints convert and validate; failures return structured 422s
  • 3Path()/Query() add ge/le, min_length/max_length, pattern + docs metadata
  • 4Fixed routes before parameterised ones; Enum params give fixed choices

Interview Questions

Sign in to ask Aria
1

How does FastAPI decide whether a function parameter is path, query, or body?

MediumGroww
2

Why must /students/me be declared before /students/{student_id}?

EasyTCS Digital
3

Design query params for a paginated, filterable product list — what limits do you enforce and why?

MediumFlipkart

Ask Aria about Path & Query Parameters — Typed and Validated

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…