← Back to FastAPI map
FastAPI · Foundations

Routing

The @app.get and @app.post decorators, the usual URL naming rules, and the options each route takes.

methods

Overview

A route binds an HTTP method and a path to a handler function. FastAPI checks routes in the order they were registered and uses the first match, which is why fixed paths must come before parameterized ones. Options on the decorator control the status code, the shape of the response, and how the endpoint appears in the docs.

Key concepts

Method meaning
GET reads, POST creates, PUT replaces, PATCH changes part of a resource, DELETE removes it. GET, PUT and DELETE are idempotent - repeating them has the same effect - while POST is not.
Registration order
/users/me must be declared before /users/{id}; otherwise "me" is captured as an id and fails int validation.
Path operation options
response_model, status_code, tags, summary and deprecated shape both the behaviour and the documentation of a route.
api_route
Registers one handler for several methods. Rarely needed - separate handlers per method read more clearly.

Best practices

  • Name resources with plural nouns (/items, /items/{id}) and let the method carry the action - not /getItems.
  • Return 201 for creation and 204 for deletes with no body.
  • Group routes with tags so /docs stays easy to navigate as the API grows.

Route decorators

All HTTP method decorators

Methods
@app.get("/items") # Read / list @app.post("/items") # Create - body required @app.put("/items/{id}") # Full update @app.patch("/items/{id}") # Partial update @app.delete("/items/{id}") # Delete @app.head("/items") # Like GET, no body @app.options("/items") # CORS preflight # Multiple methods on one handler @app.api_route("/items", methods=["GET", "POST"]) async def items_handler(): ...

Watch out: Route order matters - declare specific paths BEFORE dynamic ones: /users/me before /users/{id}, or "me" is parsed as an id.

REST endpoints - CRUD pattern

RESTful
One resource, five operations
GET/items/ · /items/{id}list all · get one
POST/items/create a new resource
PUT/items/{id}replace the entire resource
PATCH/items/{id}partial update
DELETE/items/{id}remove the resource
@app.get("/items/{id}", response_model=ItemOut) async def read(id: int): ... @app.post("/items/", status_code=201) async def create(item: ItemIn): ... @app.put("/items/{id}") async def replace(id: int, item: ItemIn): ... @app.patch("/items/{id}") async def update(id: int, item: ItemPatch): ... @app.delete("/items/{id}", status_code=204) async def delete(id: int): ...

Route decorator options

Options
@app.get( "/items/{id}", response_model=ItemOut, # filter/shape output status_code=200, # default success code tags=["items"], # group in docs summary="Get a single item", # docs title description="Long description...", response_description="Item object", deprecated=False, # shows strikethrough in docs include_in_schema=True, # hide from docs if False response_model_exclude_none=True, # strip None fields response_model_exclude_unset=True, # strip unset fields ) async def get_item(id: int): ...

Comments

Sign in to leave a comment. Your name and photo come from Google; nothing else is shared.

Loading comments...