Excerpt: FastAPI has rapidly become one of the go-to frameworks for building high-performance REST APIs in Python. In this guide, we will walk through creating a mini REST API from scratch using FastAPI, explore how it compares with Flask and Django REST Framework, and learn practical tips for testing, documentation, and deployment. By the end, you will have a production-ready microservice foundation suitable for modern distributed systems.
Introduction
FastAPI is a modern, high-performance Python web framework for building APIs with automatic OpenAPI documentation and asynchronous support. Created by SebastiΓ‘n RamΓrez, it has gained immense traction among developers since its release due to its speed, developer experience, and native integration with type hints. As of 2025, companies such as Netflix, Microsoft, and Uber are using FastAPI in various production systems.
Unlike traditional frameworks like Flask or Django REST Framework, FastAPI was built from the ground up to leverage Pythonβs asyncio capabilities and the Pydantic library for data validation. The result is a framework that feels expressive and lightweight while maintaining enterprise-grade robustness.
Why FastAPI?
Before diving into code, itβs worth examining what makes FastAPI so effective for modern API development:
- Asynchronous support built on top of Starlette for highly concurrent workloads.
- Data validation and parsing via Pydantic models with automatic error responses.
- OpenAPI and JSON Schema generation for built-in, interactive documentation via Swagger UI.
- Type safety and editor autocompletion through Python 3.9+ type hints.
- Ease of testing with
httpxandpytest.
In short, FastAPI enables you to build clean, efficient, and self-documenting APIs with minimal boilerplate.
Setting Up the Environment
To start, ensure you have Python 3.9 or higher installed. Then set up a virtual environment and install dependencies:
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install fastapi uvicorn
Key dependencies:
fastapi: The web framework itself.uvicorn: An ASGI server implementation for running the FastAPI app.
Creating the Project Structure
A minimal but scalable directory structure might look like this:
fastapi-mini-api/
βββ app/
β βββ __init__.py
β βββ main.py
β βββ models.py
β βββ schemas.py
β βββ routes/
β βββ __init__.py
β βββ items.py
βββ tests/
β βββ test_items.py
βββ requirements.txt
Step 1: Defining Data Models with Pydantic
FastAPI uses Pydantic for model validation. Define request and response schemas in schemas.py:
from pydantic import BaseModel
class Item(BaseModel):
id: int
name: str
description: str | None = None
price: float
tax: float | None = None
This ensures that every incoming request body is validated automatically, returning structured validation errors if necessary.
Step 2: Building the API Routes
Create your first route file routes/items.py:
from fastapi import APIRouter, HTTPException
from app.schemas import Item
router = APIRouter(prefix="/items", tags=["items"])
items_db = {
1: {"name": "Keyboard", "description": "Mechanical keyboard", "price": 99.99},
2: {"name": "Mouse", "description": "Wireless mouse", "price": 49.99},
}
@router.get("/{item_id}", response_model=Item)
def get_item(item_id: int):
if item_id not in items_db:
raise HTTPException(status_code=404, detail="Item not found")
return {"id": item_id, **items_db[item_id]}
@router.post("/", response_model=Item)
def create_item(item: Item):
items_db[item.id] = item.dict()
return item
Here we defined a GET and a POST endpoint. The response_model ensures output consistency, automatically filtering out unwanted fields.
Step 3: Main Application Entrypoint
Now, wire up your router in main.py:
from fastapi import FastAPI
from app.routes import items
app = FastAPI(title="Mini REST API with FastAPI", version="1.0.0")
app.include_router(items.router)
@app.get("/")
def read_root():
return {"message": "Welcome to the FastAPI mini API!"}
Run the server using Uvicorn:
(venv) $ uvicorn app.main:app --reload
You can now visit http://127.0.0.1:8000/docs to see the automatically generated Swagger UI documentation.
Visual Overview of Request Flow
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β HTTP Client β ---> β FastAPI β ---> β Router β ---> β Business β
β (curl, React)β β ASGI Layer β β (/items) β β Logic/DB β
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
Step 4: Testing the API
Testing APIs in FastAPI is straightforward using TestClient from starlette.testclient or httpx. Hereβs an example test:
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_get_item():
response = client.get("/items/1")
assert response.status_code == 200
assert response.json()["name"] == "Keyboard"
def test_post_item():
new_item = {"id": 3, "name": "Monitor", "description": "4K UHD", "price": 299.99}
response = client.post("/items/", json=new_item)
assert response.status_code == 200
assert response.json()["id"] == 3
Step 5: Adding Dependencies and Middleware
FastAPI provides a powerful dependency injection system. You can inject shared resources like database connections or configuration objects into your routes.
from fastapi import Depends
class Settings:
app_name: str = "FastAPI Mini Project"
settings = Settings()
def get_settings():
return settings
@app.get("/info")
def get_info(config: Settings = Depends(get_settings)):
return {"app_name": config.app_name}
Step 6: Error Handling and Validation
FastAPI provides built-in validation errors, but custom exception handlers make your API more robust. For example:
from fastapi.responses import JSONResponse
from fastapi.requests import Request
@app.exception_handler(ValueError)
async def value_error_handler(request: Request, exc: ValueError):
return JSONResponse(status_code=400, content={"error": str(exc)})
Now, any ValueError raised within your endpoints will produce a consistent JSON response.
Step 7: Deploying the Mini API
When deploying to production, avoid using --reload. Run with process managers or container orchestration tools:
(venv) $ uvicorn app.main:app --host 0.0.0.0 --port 80
For scaling, consider:
- Gunicorn with Uvicorn workers:
$ gunicorn -k uvicorn.workers.UvicornWorker app.main:app
- Docker for containerized deployments:
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
Performance and Benchmarking
FastAPIβs performance is one of its biggest advantages. According to independent benchmarks (2024-2025), FastAPI achieves near-parity with Node.js and Go under ASGI configurations.
Requests per Second ββββββββββββββββββββββββββββββββΊ
β GO (Fiber) ββββββββββββββββββββββ 60k
β Node.js (Express)βββββββββββββββββ 45k
β FastAPI (Uvicorn)βββββββββββββββββββ 48k
β Flask ββββββββββββ 25k
ββββββββββββββββββββββββββββββββββββββββββββββββββββΊ
Comparison: FastAPI vs Flask vs Django REST
| Framework | Async Support | Data Validation | Built-in Docs | Performance |
|---|---|---|---|---|
| FastAPI | β | β (Pydantic) | β (Swagger & ReDoc) | βββββ |
| Flask | β | β | β | βββ |
| Django REST Framework | Partial | β (Serializers) | β | βββ |
Best Practices for FastAPI Projects
- Separate routes, models, and business logic into modular components.
- Use environment variables for configuration (e.g., via
python-dotenv). - Add logging using
structlogor Pythonβs built-inlogginglibrary. - For large APIs, use
FastAPI Dependency Injectionfor scalability and maintainability. - Adopt typing rigorously for self-documenting code and improved IDE support.
Real-World Use Cases
FastAPI is widely adopted across industries:
- Netflix: For async microservices serving real-time recommendations.
- Uber: For internal ML model serving APIs.
- Microsoft: For integrating with Azure Functions.
- Startups: Rapid prototyping of microservices with full OpenAPI support.
References & Further Reading
Conclusion
FastAPI represents the new standard for Python API development. Its combination of performance, type safety, and developer experience bridges the gap between simplicity and power. Whether you are building microservices, internal APIs, or machine learning endpoints, FastAPI delivers a clean, modern foundation for building scalable systems that will serve well into 2025 and beyond.
