Claude Code Plugins

Community-maintained marketplace

Feedback

fastapi-api-patterns

@vanman2024/ai-dev-marketplace
0
0

REST API design and implementation patterns for FastAPI endpoints including CRUD operations, pagination, filtering, error handling, and request/response models. Use when building FastAPI endpoints, creating REST APIs, implementing CRUD operations, adding pagination, designing API routes, handling API errors, or when user mentions FastAPI patterns, REST API design, endpoint structure, API best practices, or HTTP endpoints.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name fastapi-api-patterns
description REST API design and implementation patterns for FastAPI endpoints including CRUD operations, pagination, filtering, error handling, and request/response models. Use when building FastAPI endpoints, creating REST APIs, implementing CRUD operations, adding pagination, designing API routes, handling API errors, or when user mentions FastAPI patterns, REST API design, endpoint structure, API best practices, or HTTP endpoints.
allowed-tools Bash, Read, Write, Edit, WebFetch

fastapi-api-patterns

Instructions

This skill provides comprehensive REST API design patterns and implementation templates for FastAPI applications. It covers CRUD operations, pagination, filtering, request/response models, error handling, and API organization following modern best practices.

1. CRUD Endpoint Patterns

Create, Read, Update, Delete endpoints using FastAPI routers:

# Use CRUD template to generate complete endpoint set
cp ./skills/fastapi-api-patterns/templates/crud_endpoint.py app/routers/items.py

# Customize for your model
# - Replace Item model with your Pydantic model
# - Update database operations
# - Add authentication dependencies

What This Provides:

  • POST /items/ - Create new item
  • GET /items/{item_id} - Read single item by ID
  • GET /items/ - Read multiple items with pagination
  • PUT /items/{item_id} - Update entire item
  • PATCH /items/{item_id} - Partial update
  • DELETE /items/{item_id} - Delete item

Router Structure:

from fastapi import APIRouter, HTTPException, Depends, status
from typing import List

router = APIRouter(
    prefix="/items",
    tags=["items"],
    responses={404: {"description": "Not found"}},
)

2. Pagination and Filtering

Implement pagination with query parameters:

# Use pagination template
cp ./skills/fastapi-api-patterns/templates/pagination.py app/utils/pagination.py

Pagination Strategies:

1. Offset-Based Pagination (Simple):

@router.get("/items/")
async def list_items(skip: int = 0, limit: int = 10):
    return items[skip : skip + limit]

2. Cursor-Based Pagination (Performance):

@router.get("/items/")
async def list_items(cursor: str | None = None, limit: int = 10):
    # Use last item ID as cursor for next page
    # Better for large datasets

3. Page-Based Pagination (User-Friendly):

@router.get("/items/")
async def list_items(page: int = 1, page_size: int = 10):
    skip = (page - 1) * page_size
    return items[skip : skip + page_size]

Filtering Patterns:

@router.get("/items/")
async def list_items(
    skip: int = 0,
    limit: int = 10,
    category: str | None = None,
    min_price: float | None = None,
    max_price: float | None = None,
    search: str | None = None,
):
    # Apply filters before pagination
    filtered_items = apply_filters(items, category, min_price, max_price, search)
    return filtered_items[skip : skip + limit]

Sorting:

from enum import Enum

class SortBy(str, Enum):
    name = "name"
    price = "price"
    created_at = "created_at"

@router.get("/items/")
async def list_items(
    sort_by: SortBy = SortBy.created_at,
    order: Literal["asc", "desc"] = "desc",
):
    # Sort before returning

3. Request and Response Models

Define clear Pydantic models for type safety and validation:

Base Models:

from pydantic import BaseModel, Field, validator
from datetime import datetime

class ItemBase(BaseModel):
    """Shared properties"""
    name: str = Field(..., min_length=1, max_length=100)
    description: str | None = Field(None, max_length=500)
    price: float = Field(..., gt=0)
    category: str

class ItemCreate(ItemBase):
    """Properties required for creation"""
    pass

class ItemUpdate(BaseModel):
    """Properties that can be updated"""
    name: str | None = None
    description: str | None = None
    price: float | None = Field(None, gt=0)
    category: str | None = None

class ItemInDB(ItemBase):
    """Properties stored in database"""
    id: int
    created_at: datetime
    updated_at: datetime

class Item(ItemInDB):
    """Properties returned to client"""
    class Config:
        from_attributes = True

Response Models with Metadata:

from typing import Generic, TypeVar, List
from pydantic import BaseModel

T = TypeVar('T')

class PaginatedResponse(BaseModel, Generic[T]):
    items: List[T]
    total: int
    page: int
    page_size: int
    pages: int

@router.get("/items/", response_model=PaginatedResponse[Item])
async def list_items(page: int = 1, page_size: int = 10):
    total = len(items)
    pages = (total + page_size - 1) // page_size
    skip = (page - 1) * page_size

    return PaginatedResponse(
        items=items[skip : skip + page_size],
        total=total,
        page=page,
        page_size=page_size,
        pages=pages,
    )

4. Error Handling Strategies

Implement consistent error handling:

# Use error handling template
cp ./skills/fastapi-api-patterns/templates/error_handling.py app/utils/errors.py

HTTP Exception Patterns:

from fastapi import HTTPException, status

# 404 Not Found
if item is None:
    raise HTTPException(
        status_code=status.HTTP_404_NOT_FOUND,
        detail=f"Item with id {item_id} not found"
    )

# 400 Bad Request
if price < 0:
    raise HTTPException(
        status_code=status.HTTP_400_BAD_REQUEST,
        detail="Price must be positive"
    )

# 409 Conflict
if item_exists:
    raise HTTPException(
        status_code=status.HTTP_409_CONFLICT,
        detail="Item with this name already exists"
    )

# 403 Forbidden
if not is_owner:
    raise HTTPException(
        status_code=status.HTTP_403_FORBIDDEN,
        detail="Not authorized to modify this item"
    )

Custom Exception Handlers:

from fastapi import Request
from fastapi.responses import JSONResponse

class ItemNotFoundError(Exception):
    def __init__(self, item_id: int):
        self.item_id = item_id

@app.exception_handler(ItemNotFoundError)
async def item_not_found_handler(request: Request, exc: ItemNotFoundError):
    return JSONResponse(
        status_code=404,
        content={
            "error": "not_found",
            "message": f"Item {exc.item_id} not found",
            "item_id": exc.item_id
        }
    )

Validation Error Customization:

from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    return JSONResponse(
        status_code=422,
        content={
            "error": "validation_error",
            "message": "Invalid request data",
            "details": exc.errors()
        }
    )

5. Dependency Injection for Common Logic

Use dependencies for authentication, database sessions, and validation:

from fastapi import Depends, Header, HTTPException

# Authentication dependency
async def verify_token(x_token: str = Header(...)):
    if x_token != "secret-token":
        raise HTTPException(status_code=401, detail="Invalid token")
    return x_token

# Database session dependency
async def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# Pagination dependency
async def pagination_params(
    skip: int = 0,
    limit: int = 10,
    max_limit: int = 100
):
    if limit > max_limit:
        limit = max_limit
    return {"skip": skip, "limit": limit}

# Use in endpoints
@router.get("/items/")
async def list_items(
    token: str = Depends(verify_token),
    db: Session = Depends(get_db),
    pagination: dict = Depends(pagination_params),
):
    return db.query(Item).offset(pagination["skip"]).limit(pagination["limit"]).all()

6. API Router Organization

Structure APIs with APIRouter for modularity:

# app/routers/items.py
from fastapi import APIRouter

router = APIRouter(
    prefix="/items",
    tags=["items"],
    dependencies=[Depends(verify_token)],
    responses={404: {"description": "Not found"}},
)

# app/main.py
from fastapi import FastAPI
from app.routers import items, users

app = FastAPI()

app.include_router(items.router)
app.include_router(users.router, prefix="/api/v1")

7. OpenAPI Documentation Enhancement

Generate better API documentation:

# Generate enhanced OpenAPI docs
bash ./skills/fastapi-api-patterns/scripts/generate-openapi-docs.sh

Endpoint Documentation:

@router.post(
    "/items/",
    response_model=Item,
    status_code=status.HTTP_201_CREATED,
    summary="Create a new item",
    description="Create a new item with the provided data",
    response_description="The created item",
    responses={
        201: {"description": "Item created successfully"},
        400: {"description": "Invalid input data"},
        409: {"description": "Item already exists"},
    }
)
async def create_item(item: ItemCreate):
    """
    Create a new item with all the information:

    - **name**: Item name (required, 1-100 characters)
    - **description**: Item description (optional, max 500 characters)
    - **price**: Item price (required, must be positive)
    - **category**: Item category (required)
    """
    pass

Examples

Example 1: Complete CRUD API for Chat Messages

# Copy chat API example
cp ./skills/fastapi-api-patterns/examples/chat_api.py app/routers/chat.py

Features:

  • Create chat messages
  • List messages with pagination and filtering
  • Get single message by ID
  • Update message content
  • Delete messages
  • Search messages by content
  • Filter by user, channel, date range

Result: Production-ready chat message API with full CRUD operations

Example 2: User Management API

# Copy user management example
cp ./skills/fastapi-api-patterns/examples/user_management.py app/routers/users.py

Features:

  • User registration with validation
  • User authentication (simulated)
  • Profile retrieval and updates
  • Password change endpoint
  • List users with role filtering
  • User deactivation (soft delete)

Result: Complete user management system with security best practices

Example 3: Memory/Context Endpoints for AI Applications

# Copy memory endpoints example
cp ./skills/fastapi-api-patterns/examples/memory_endpoints.py app/routers/memory.py

Features:

  • Store conversation context
  • Retrieve context by session ID
  • Update context with new messages
  • Clear old contexts
  • Search contexts by keywords
  • Pagination for large context histories

Result: API for managing AI conversation memory and context

Requirements

Dependencies:

  • FastAPI 0.100+
  • Pydantic 2.0+
  • Python 3.10+

Optional Dependencies:

  • SQLAlchemy (for database operations)
  • python-jose (for JWT authentication)
  • passlib (for password hashing)
  • python-multipart (for file uploads)

Project Structure:

app/
├── main.py
├── routers/
│   ├── __init__.py
│   ├── items.py
│   ├── users.py
│   └── chat.py
├── models/
│   ├── __init__.py
│   └── schemas.py
├── utils/
│   ├── pagination.py
│   └── errors.py
└── dependencies.py

Best Practices

1. Use Response Models:

  • Always specify response_model to control what's returned
  • Use separate models for create, update, and read operations
  • Never expose sensitive data (passwords, tokens)

2. Consistent Error Responses:

  • Use standard HTTP status codes
  • Return structured error objects with error, message, and details
  • Include request ID for debugging

3. Pagination Everywhere:

  • Never return unbounded lists
  • Default to reasonable page sizes (10-50 items)
  • Include total count and page metadata

4. Validation and Documentation:

  • Use Pydantic Field validators for complex validation
  • Document all endpoints with descriptions and examples
  • Use response examples in OpenAPI schema

5. Dependencies for Reusability:

  • Extract common logic into dependencies
  • Use dependency injection for auth, DB, pagination
  • Keep endpoints thin, move logic to services

6. Versioning:

  • Use prefix-based versioning (/api/v1/items)
  • Keep old versions running during migration
  • Document breaking changes clearly

Validation Script

Validate endpoint structure and best practices:

# Validate all endpoints in a router file
bash ./skills/fastapi-api-patterns/scripts/validate-endpoints.sh app/routers/items.py

# What it checks:
# - Response models defined
# - Status codes specified
# - Error handling present
# - Documentation strings
# - Proper HTTP methods
# - Path parameter validation

Performance Considerations

Database Queries:

  • Use pagination to limit query size
  • Add indexes on frequently filtered fields
  • Use database-level filtering, not Python filtering
  • Implement query result caching for expensive operations

Response Size:

  • Exclude unnecessary fields from responses
  • Support field selection via query params
  • Compress responses with gzip middleware
  • Use streaming for large responses

Request Validation:

  • Set reasonable limits on request sizes
  • Validate early and fail fast
  • Use background tasks for heavy processing
  • Implement rate limiting on expensive endpoints

Plugin: fastapi-backend Version: 1.0.0 Category: API Development Skill Type: REST API Patterns