Skip to course content
Free FastAPI backend course

FastAPI for AI Backend Development

Unit 04.00: Path parameters and what belongs in a path

Paths identify a resource. Everything optional belongs somewhere else.

Four purposes, three locations

What goes in the path, the query and the headers.

The code shows a path parameter and then the rule.

from fastapi import FastAPI
from fastapi.testclient import TestClient

app = FastAPI()


@app.get("/invoices/{invoice_id}")
def get_invoice(invoice_id: str) -> dict:
    return {"invoice_id": invoice_id}


client = TestClient(app)
print(client.get("/invoices/INV-1").json())

RULES = [
    ("identifies the resource",         "path",  "/invoices/INV-1"),
    ("filters or sorts a collection",   "query", "/invoices?status=open"),
    ("optional, with a default",        "query", "/invoices?limit=50"),
    ("carries credentials",             "header", "Authorization"),
]
print()
for purpose, where, example in RULES:
    print(f"{purpose:34} {where:8} {example}")

print("\nPaths identify. Anything optional or repeated belongs in the query.")

A path parameter is part of the resource's identity, so /invoices/INV-1 names a thing. /invoices?id=INV-1 names a collection and filters it, which is a different resource with different caching behaviour.

Credentials go in headers for the reason the security module covers: query strings are written to every access log they pass through.

The mistake this prevents

The mistake is putting an optional value in the path. It forces two route definitions or a sentinel value in the URL, and it makes the path mean different things depending on what is in it.

Takeaway

Paths identify, queries filter and page, headers carry credentials and content negotiation. Anything optional does not belong in a path.