Building API design and documentation with FastAPI and Ex...
This guide provides a structured approach to building API-first products with focus on implementation, tooling, and production considerations. Follow these steps to create a scalable, well-documented API product that addresses common developer pain points.
Define API endpoints with OpenAPI specification
Create a formal OpenAPI 3.1 document that defines all endpoints, request/response formats, and security requirements. Use this as the single source of truth for implementation.
openapi: 3.1.0
info:
title: Product API
version: 1.0.0
paths:
/products:
get:
summary: List products
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
type: object
properties:
id: { type: string }
name: { type: string }⚠ Common Pitfalls
- •Not updating the spec after implementation changes
- •Using inconsistent data types between spec and code
Implement authentication and rate limiting
Integrate Unkey for API key management and configure rate limits using middleware. Apply these to all endpoints with proper error responses for unauthorized/overaged requests.
from unkey import Unkey
unkey = Unkey(api_key="YOUR_API_KEY")
@app.middleware("http")
def rate_limit(request, call_next):
key = request.headers.get("Authorization")
if not unkey.verify_key(key):
return JSONResponse(status_code=401, content={"error": "Invalid API key"})
if unkey.rate_limit(key, "products.get", 100):
return JSONResponse(status_code=429, content={"error": "Rate limit exceeded"})
return call_next(request)⚠ Common Pitfalls
- •Not handling rate limit exhaustion gracefully
- •Using weak authentication mechanisms without rotation
Implement versioning strategy
Use URL versioning (e.g., /v1/products) and maintain backward compatibility. Document deprecation schedules for outdated versions.
from fastapi import APIRouter
router = APIRouter(prefix="/v1")
@router.get("/products")
def get_products():
return {"version": "v1", "data": [...]}⚠ Common Pitfalls
- •Changing request/response formats without deprecation warnings
- •Not maintaining multiple versions in parallel
Generate and maintain documentation
Use Swagger UI or ReDoc to auto-generate documentation from the OpenAPI spec. Set up CI/CD to validate spec consistency with implementation.
npx @openapitools/openapi-generator-cli generate -i openapi.yaml -g html -o ./docs⚠ Common Pitfalls
- •Allowing documentation to become outdated
- •Not testing documentation against actual endpoints
Implement usage-based pricing
Integrate Stripe Billing to track API usage metrics. Create pricing tiers that align with your monetization strategy.
import stripe
stripe.api_key = "sk_test_..."
def calculate_cost(usage):
return stripe.Price.create(
unit_amount=1000 * usage,
currency="usd",
product="prod_123",
tiers=[
{"up_to": 1000, "unit_amount": 1000},
{"up_to": 5000, "unit_amount": 800}
]
)⚠ Common Pitfalls
- •Not tracking usage metrics accurately
- •Ignoring proration rules for tiered pricing
What you built
By following this implementation sequence, you'll create a production-ready API product that balances developer experience with business requirements. Ensure all components are tested in staging environments before public deployment.