FastAPI Essentials

Course Content

FastAPI Essentials

1 sections · 32 lessons

Explain the difference between path parameters and query parameters in FastAPI.


What you need to know

Path parameterQuery parameter
Where in the URLInside the path: /documents/{doc_id}After ?: ?page=2&size=20
PurposeIdentifies which resourceChanges how you get it: filter, page, sort, flags
Required?AlwaysOptional if it has a default
Missing valueThe URL does not match: 404422 if required, default otherwise
Validation helperPath(ge=1)Query(ge=1, le=100)
Python
from typing import Annotated, Literalfrom fastapi import FastAPI, Path, Queryapp = FastAPI()@app.get("/documents/{doc_id}/chunks")def list_chunks(    doc_id: Annotated[int, Path(ge=1)],                  # which document    page: Annotated[int, Query(ge=1)] = 1,               # how to slice the result    size: Annotated[int, Query(ge=1, le=100)] = 20,    lang: Literal["en", "hi", "ta"] | None = None,):    return {"doc_id": doc_id, "page": page, "size": size, "lang": lang}

Real responses:

Text
GET /documents/42/chunks?page=2&lang=hi  -> {'doc_id': 42, 'page': 2, 'size': 20, 'lang': 'hi'}GET /documents/42/chunks                 -> {'doc_id': 42, 'page': 1, 'size': 20, 'lang': None}GET /documents/0/chunks?size=500         -> 422 [(['path', 'doc_id'], '... greater than or equal to 1'),                                                 (['query', 'size'], '... less than or equal to 100')]GET /documents//chunks                   -> 404GET /documents/42/chunks?lang=fr         -> 422 Input should be 'en', 'hi' or 'ta'

Notice the difference in the last lines. An empty path segment does not match the route at all, so it is a 404. A bad query value matches the route but fails validation, so it is a 422, and the error's loc says whether the problem was in path or query.

Design guidance

  • Use a path parameter for identity: /models/{model_id}, /documents/{doc_id}.
  • Use query parameters for pagination, filters, sorting and optional flags: ?page=2&lang=hi&rerank=true.
  • A good test: if removing the value makes the URL point to a different kind of thing, it belongs in the path.
  • Never put prompts, API keys or personal data in either. URLs are written to access logs, proxy logs and browser history, and have length limits (often around 8 KB). Those go in the request body or a header.

A real-life example

A RAG product's first search endpoint was GET /search?q=..., with the user's full question in the query string. A security review found customer questions — some including phone numbers and account details — in the load balancer's access logs, which were kept for 90 days and readable by the whole platform team.

The team moved search to POST /search with the question in a JSON body, and kept only non-sensitive options in the query string (?top_k=5&lang=hi). Document lookups stayed as GET /documents/{doc_id}, because an id is safe to log and GET makes them cacheable.

Follow-up questions to expect

  • "How do you accept a list in a query string?" — Declare tags: Annotated[list[str], Query()] = [] and send ?tags=a&tags=b.
  • "Can a path parameter contain a slash?" — Only with the :path converter: /files/{file_path:path}. Validate it carefully to avoid path traversal.
  • "How do you make a query parameter required?" — Give it no default: q: str. FastAPI returns 422 if it is missing.