Skip to content

FastAPI Framework Introduction

Overview

FastAPI is a modern, fast (high-performance) web framework for building APIs, based on standard Python type hints. Created by Sebastián Ramirez in 2018, it aims to combine features from multiple excellent frameworks to provide a web framework that is both high-performance and easy to use.

🚀 Background of FastAPI

Challenges of Traditional Python Web Frameworks

Before FastAPI appeared, Python web development faced some challenges:

python
# Flask Example - Lacks type validation
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    # Need to manually validate parameters
    if not isinstance(user_id, int):
        return jsonify({'error': 'Invalid user ID'}), 400
    # Need to manually write documentation
    return jsonify({'user_id': user_id, 'name': 'John'})
python
# Django REST Framework Example - Quite complex
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers

class UserSerializer(serializers.Serializer):
    user_id = serializers.IntegerField()
    name = serializers.CharField()

class UserView(APIView):
    def get(self, request, user_id):
        # Need more boilerplate code
        serializer = UserSerializer(data={'user_id': user_id, 'name': 'John'})
        return Response(serializer.data)

FastAPI's Solution

python
# FastAPI Example - Concise and feature-complete
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    user_id: int
    name: str

@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: int):
    # Automatic type validation, documentation generation, serialization
    return User(user_id=user_id, name="John")

💡 Core Features

1. High Performance

FastAPI is based on Starlette and Pydantic, with performance comparable to NodeJS and Go:

python
# Performance benchmark results (requests/second)
frameworks_performance = {
    "FastAPI": "~60,000",
    "Flask": "~20,000",
    "Django": "~15,000",
    "Express (NodeJS)": "~65,000",
    "Gin (Go)": "~70,000"
}

2. Automatic Type Validation

Automatic validation based on Python type hints:

python
from fastapi import FastAPI, Query, Path
from typing import Optional
from datetime import datetime
from pydantic import BaseModel, EmailStr

app = FastAPI()

class UserCreate(BaseModel):
    name: str
    email: EmailStr
    age: int
    birth_date: Optional[datetime] = None

@app.post("/users/")
async def create_user(
    user: UserCreate,
    priority: int = Query(..., ge=1, le=10, description="Priority 1-10")
):
    # FastAPI automatically validates:
    # - All field types of user object
    # - Email format
    # - Priority range (1-10)
    # - Returns 422 error if validation fails
    return {"user": user, "priority": priority}

3. Automatic Documentation Generation

Automatically generates interactive documentation based on OpenAPI and JSON Schema:

python
@app.get("/items/{item_id}")
async def read_item(
    item_id: int = Path(..., title="Item ID", description="Unique identifier of the item to retrieve"),
    q: Optional[str] = Query(None, max_length=50, description="Optional query string")
):
    """
    Get item information

    - **item_id**: Unique ID of the item
    - **q**: Optional search query

    Returns detailed item information
    """
    return {"item_id": item_id, "q": q}

# Visit http://localhost:8000/docs to see Swagger UI
# Visit http://localhost:8000/redoc to see ReDoc

4. Modern Python Features Support

Fully supports modern Python features:

python
from typing import List, Dict, Union, Optional
from fastapi import FastAPI
from pydantic import BaseModel

# Type hints
@app.get("/items/", response_model=List[Dict[str, Union[str, int]]])
async def read_items():
    return [{"name": "item1", "price": 100}]

# Async support
import asyncio
import httpx

@app.get("/external-data/")
async def get_external_data():
    async with httpx.AsyncClient() as client:
        response = await client.get("https://api.example.com/data")
        return response.json()

# Dependency injection
from fastapi import Depends

async def get_database():
    # Database connection logic
    db = "database_connection"
    try:
        yield db
    finally:
        # Cleanup logic
        pass

@app.get("/users/")
async def read_users(db=Depends(get_database)):
    # Automatically inject database connection
    return {"users": [], "db": str(db)}

🏗️ Architecture Design

Core Component Architecture

mermaid
graph TB
    subgraph "FastAPI Core"
        FastAPI[FastAPI App]
        Router[Router]
        Middleware[Middleware Stack]
    end

    subgraph "Base Layer"
        Starlette[Starlette ASGI]
        Pydantic[Pydantic Validation]
        Uvicorn[Uvicorn Server]
    end

    subgraph "Extension Layer"
        OpenAPI[OpenAPI Schema]
        SwaggerUI[Swagger UI]
        ReDoc[ReDoc]
    end

    FastAPI --> Router
    FastAPI --> Middleware
    FastAPI --> Starlette
    FastAPI --> Pydantic
    Starlette --> Uvicorn
    FastAPI --> OpenAPI
    OpenAPI --> SwaggerUI
    OpenAPI --> ReDoc

Request Processing Flow

mermaid
sequenceDiagram
    participant Client
    participant Uvicorn
    participant Middleware
    participant FastAPI
    participant Pydantic
    participant Handler

    Client->>Uvicorn: HTTP Request
    Uvicorn->>Middleware: ASGI Request
    Middleware->>FastAPI: Processed Request
    FastAPI->>Pydantic: Validate Input
    Pydantic->>FastAPI: Validated Data
    FastAPI->>Handler: Call Route Handler
    Handler->>FastAPI: Response Data
    FastAPI->>Pydantic: Serialize Response
    Pydantic->>FastAPI: Serialized Data
    FastAPI->>Middleware: HTTP Response
    Middleware->>Uvicorn: Final Response
    Uvicorn->>Client: HTTP Response

🛠️ Tech Stack Comparison

FastAPI vs Other Frameworks

FeatureFastAPIFlaskDjangoExpress.js
Performance⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Ease of Use⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Type Safety⭐⭐⭐⭐⭐⭐⭐⭐⭐
Auto Documentation⭐⭐⭐⭐⭐⭐⭐⭐⭐
Async Support⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Ecosystem⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

Reasons to Choose FastAPI

python
# 1. High development efficiency
@app.post("/users/", response_model=User)
async def create_user(user: UserCreate):
    # One line achieves validation, serialization, documentation generation
    return await user_service.create(user)

# 2. Type safety
def process_user(user_id: int, user: User) -> UserResponse:
    # IDE provides complete code completion and error checking
    return UserResponse(
        id=user_id,
        name=user.name,
        created_at=datetime.now()
    )

# 3. Easy to test
from fastapi.testclient import TestClient

client = TestClient(app)

def test_create_user():
    response = client.post("/users/", json={"name": "test", "email": "test@example.com"})
    assert response.status_code == 200
    assert response.json()["name"] == "test"

🌟 Main Advantages

1. Developer Experience

  • Intelligent Code Completion: IDE support based on type hints
  • Automatic Error Detection: Find potential issues at compile time
  • Hot Reload: Automatically restart server during development

2. Production Ready

python
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware

app = FastAPI(
    title="Production API",
    description="Production-grade API service",
    version="1.0.0",
    docs_url="/api/docs",  # Customizable documentation path
    redoc_url="/api/redoc"
)

# CORS support
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://myapp.com"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Compression middleware
app.add_middleware(GZipMiddleware, minimum_size=1000)

3. Standard Compliance

  • OpenAPI 3.0: Fully compatible with OpenAPI specification
  • JSON Schema: Automatically generate standard JSON Schema
  • OAuth2: Built-in authentication support
  • JWT: Token authentication integration

🔧 Ecosystem

Core Dependencies

python
# FastAPI's core dependency stack
dependencies = {
    "starlette": "ASGI framework base",
    "pydantic": "Data validation and serialization",
    "uvicorn": "ASGI server",
    "python-multipart": "Forms and file uploads",
    "jinja2": "Template engine (optional)",
    "python-jose": "JWT handling (optional)"
}

Common Extensions

python
# Database
from sqlalchemy import create_engine
from databases import Database

# Cache
import redis
from fastapi_cache import FastAPICache

# Authentication
from fastapi_users import FastAPIUsers
from passlib.context import CryptContext

# Testing
from httpx import AsyncClient
import pytest

# Deployment
# uvicorn, gunicorn, docker

Third-party Tools

  • FastAPI Users: User authentication system
  • SQLModel: Database ORM (developed by FastAPI author)
  • FastAPI Cache: Cache solution
  • FastAPI Limiter: API rate limiting
  • Tortoise ORM: Async ORM
  • Celery: Task queue integration

📈 Performance Features

Async Processing

python
import asyncio
from fastapi import FastAPI

app = FastAPI()

@app.get("/sync-endpoint/")
def sync_endpoint():
    # Synchronous processing - blocks event loop
    time.sleep(1)
    return {"message": "sync"}

@app.get("/async-endpoint/")
async def async_endpoint():
    # Asynchronous processing - doesn't block event loop
    await asyncio.sleep(1)
    return {"message": "async"}

# Async endpoints can handle multiple requests simultaneously
# Sync endpoints will block other requests

Performance Optimization Suggestions

python
# 1. Use async database drivers
import asyncpg
from databases import Database

database = Database("postgresql://user:pass@localhost/db")

# 2. Connection pool management
from sqlalchemy.pool import QueuePool

engine = create_async_engine(
    DATABASE_URL,
    poolclass=QueuePool,
    pool_size=20,
    max_overflow=0
)

# 3. Response caching
from fastapi_cache import FastAPICache
from fastapi_cache.backends.redis import RedisBackend

@app.on_event("startup")
async def startup():
    redis = aioredis.from_url("redis://localhost")
    FastAPICache.init(RedisBackend(redis), prefix="fastapi-cache")

@app.get("/cached-data/")
@cache(expire=60)
async def get_cached_data():
    # Cache for 60 seconds
    return expensive_computation()

🎯 Use Cases

Best Suited For

  • API-first Applications: Microservices, RESTful APIs
  • Rapid Prototyping: MVPs, concept validation
  • Data Science APIs: ML model serving, data analysis
  • Modern Web Applications: SPA backends, mobile app APIs

Not Well Suited For

  • Traditional Web Applications: Multi-page applications requiring server-side rendering
  • Simple Scripts: Over-engineering
  • Legacy System Integration: May require special compatibility handling

📚 Learning Resources

Official Resources

Community Resources

Summary

FastAPI represents the new generation direction of Python web frameworks. It successfully combines performance, ease of use, and modern development experience. By leveraging Python's type system, FastAPI achieves:

  • Extremely High Development Efficiency
  • Excellent Runtime Performance
  • Powerful Type Safety
  • Automatic Documentation Generation
  • Modern Development Experience

In the following chapters, we will dive deep into how to set up a FastAPI development environment and start building our first application.

Why Choose FastAPI?

If you're looking for a modern and high-performance Python web framework, FastAPI is one of the best choices available today. It allows you to quickly build APIs while ensuring code quality and maintainability.

Content is for learning and research only.