Skip to main content

FastAPI Path Operation Decorators

Introduction

In FastAPI, path operation decorators are a crucial feature that allows you to define API endpoints with specific HTTP methods. These decorators connect your Python functions to specific URL paths, creating what are called "path operations" in FastAPI terminology.

A path operation is a combination of:

  • A specific HTTP method (GET, POST, PUT, DELETE, etc.)
  • A specific URL path (like /items/, /users/{user_id})
  • A function that will handle requests to that path with that method

Path operation decorators make your API code expressive, easy to read, and well-organized.

Basic Path Operation Decorators

FastAPI provides decorators for all standard HTTP methods. Let's look at the most common ones:

GET Requests

The @app.get() decorator is used for retrieving data without changing the server state.

python
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
return {"message": "Hello World"}

When you visit the root URL / in a browser, you'll see:

json
{
"message": "Hello World"
}

POST Requests

The @app.post() decorator is used for creating new data:

python
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
name: str
price: float

@app.post("/items/")
def create_item(item: Item):
return {"item_name": item.name, "item_price": item.price, "message": "Item created"}

Sending a POST request with the following JSON body:

json
{
"name": "Laptop",
"price": 999.99
}

Will result in:

json
{
"item_name": "Laptop",
"item_price": 999.99,
"message": "Item created"
}

PUT Requests

Use @app.put() for updating existing resources:

python
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_id": item_id, "item_name": item.name, "item_price": item.price}

DELETE Requests

Use @app.delete() for removing resources:

python
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
return {"item_id": item_id, "message": "Item deleted"}

Advanced Path Operation Decorators

FastAPI allows you to customize how path operations work beyond just specifying the HTTP method and path.

Status Codes

You can specify the response status code:

python
from fastapi import FastAPI, status

app = FastAPI()

@app.post("/items/", status_code=status.HTTP_201_CREATED)
def create_item(name: str):
return {"name": name}

This example will return HTTP status code 201 (Created) instead of the default 200 (OK).

Response Model

You can define the exact structure of your response:

python
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List

app = FastAPI()

class Item(BaseModel):
name: str
price: float

class ItemResponse(BaseModel):
id: int
name: str
price: float

@app.post("/items/", response_model=ItemResponse)
def create_item(item: Item):
# In a real app, we'd save to a database here
return {"id": 1, "name": item.name, "price": item.price}

This ensures that the response will match the ItemResponse model and automatically generates proper API documentation.

Multiple Path Parameters

You can use multiple parameters in your paths:

python
@app.get("/users/{user_id}/items/{item_id}")
def get_user_item(user_id: int, item_id: int):
return {"user_id": user_id, "item_id": item_id}

For example, /users/1/items/42 would return:

json
{
"user_id": 1,
"item_id": 42
}

Tags and Documentation

You can organize your API endpoints with tags:

python
@app.get("/users/", tags=["users"])
def get_users():
return [{"name": "Harry"}, {"name": "Ron"}]

@app.get("/items/", tags=["items"])
def get_items():
return [{"name": "Wand"}, {"name": "Broomstick"}]

These tags will group your endpoints in the automatically generated documentation.

Real-World Example: Building a Simple To-Do API

Let's build a simple to-do API using different path operation decorators:

python
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel
from typing import List, Optional

app = FastAPI()

# Our data model
class Todo(BaseModel):
title: str
description: Optional[str] = None
completed: bool = False

# In-memory database
todos = {}
todo_id_counter = 1

# Create a new todo
@app.post("/todos/", status_code=status.HTTP_201_CREATED, response_model=Todo)
def create_todo(todo: Todo):
global todo_id_counter
todos[todo_id_counter] = todo
new_todo = todo.dict()
new_todo["id"] = todo_id_counter
todo_id_counter += 1
return new_todo

# Get all todos
@app.get("/todos/", response_model=List[dict])
def get_todos():
result = []
for id, todo in todos.items():
todo_dict = todo.dict()
todo_dict["id"] = id
result.append(todo_dict)
return result

# Get a specific todo
@app.get("/todos/{todo_id}", response_model=dict)
def get_todo(todo_id: int):
if todo_id not in todos:
raise HTTPException(status_code=404, detail="Todo not found")
todo_dict = todos[todo_id].dict()
todo_dict["id"] = todo_id
return todo_dict

# Update a todo
@app.put("/todos/{todo_id}", response_model=dict)
def update_todo(todo_id: int, todo: Todo):
if todo_id not in todos:
raise HTTPException(status_code=404, detail="Todo not found")
todos[todo_id] = todo
todo_dict = todo.dict()
todo_dict["id"] = todo_id
return todo_dict

# Delete a todo
@app.delete("/todos/{todo_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_todo(todo_id: int):
if todo_id not in todos:
raise HTTPException(status_code=404, detail="Todo not found")
del todos[todo_id]
return None

This example demonstrates how different HTTP methods can be used to create a RESTful API for managing todos.

Path Operation Decorator Parameters

FastAPI's path operation decorators support several parameters:

ParameterDescriptionExample
response_modelDefines the model used for the response@app.get("/items/", response_model=List[Item])
status_codeSets the HTTP status code for the response@app.post("/items/", status_code=201)
tagsGroups operations in the documentation@app.get("/items/", tags=["items"])
summaryProvides a summary for the documentation@app.get("/items/", summary="Get all items")
descriptionAdds a detailed description@app.get("/items/", description="Get all items from the database")
response_descriptionDescribes the response@app.get("/items/", response_description="List of items")
deprecatedMarks an operation as deprecated@app.get("/items/", deprecated=True)

Summary

Path operation decorators in FastAPI are a powerful way to define your API endpoints. They allow you to:

  1. Connect URL paths with specific HTTP methods and Python functions
  2. Specify response models and status codes
  3. Add metadata for API documentation
  4. Create clear, organized, and maintainable API code

By using the appropriate decorators (@app.get(), @app.post(), @app.put(), @app.delete(), etc.), you can build RESTful APIs that follow best practices and are well-documented automatically.

Additional Resources

Exercises

  1. Create a simple API with endpoints for managing a library of books using all CRUD operations (Create, Read, Update, Delete).
  2. Implement an API endpoint that returns different status codes based on certain conditions.
  3. Build an API with endpoints grouped by tags for better documentation organization.
  4. Create an endpoint with a custom response model that transforms the data before returning it to the client.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)