Skip to content

FastAPI 完整实战手册

导航目录

一、前言:简介、价值、场景、安装、依赖、环境验证

1.1 FastAPI 简介

核心说明
FastAPI 是基于 Python 类型提示构建的现代 Web API 框架,具备高性能、自动文档、强校验、异步支持等特性。非常适合 API 开发、前后端分离项目、微服务以及轻量后端服务。

1.2 核心价值

  • 高性能:基于 Starlette + ASGI,吞吐高
  • 自动文档:内置 Swagger UI 与 ReDoc
  • 类型安全:Pydantic 自动做请求/响应数据校验
  • 异步友好:天然支持 async/await

1.3 应用场景

  • RESTful API 开发
  • 前后端分离项目后端
  • 微服务系统
  • AI/数据服务接口层
  • 内部工具平台 API

1.4 安装方法(pip + 镜像)

bash
pip install fastapi uvicorn pydantic sqlalchemy python-multipart python-jose[cryptography] passlib[bcrypt]
bash
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple fastapi uvicorn pydantic sqlalchemy python-multipart python-jose[cryptography] passlib[bcrypt]

1.5 核心依赖说明

  • Python:3.9+
  • FastAPI:Web 框架
  • Uvicorn:ASGI 服务器
  • Pydantic:数据验证与序列化
  • SQLAlchemy:ORM(数据库场景)

1.6 基础运行验证

基础接口搭建代码示例

python
from fastapi import FastAPI

app = FastAPI(title="FastAPI Quick Start")

@app.get("/")
def root():
    return {"message": "FastAPI is running"}

# 启动命令:
# uvicorn main:app --reload

运行效果说明

  • 访问 http://127.0.0.1:8000/ 返回 JSON
  • 访问 http://127.0.0.1:8000/docs 查看 Swagger UI
  • 访问 http://127.0.0.1:8000/redoc 查看 ReDoc

二、入门基础:核心概念、开发流程、基础组件、常见误区

2.1 FastAPI 核心概念

核心说明

  • 应用实例app = FastAPI()
  • 路由@app.get/post/put/delete(...)
  • 请求方法:GET/POST/PUT/DELETE 等
  • 路径参数/users/{user_id}
  • 查询参数/users?name=tom
  • 请求体:通常使用 Pydantic 模型
  • 响应体:返回 dict 或模型
  • 接口文档:自动生成 Swagger/ReDoc

2.2 基础开发流程

  1. 环境搭建
  2. 导入依赖
  3. 创建 FastAPI 实例
  4. 定义路由接口
  5. 运行 Uvicorn
  6. 访问接口与文档
  7. 调试与优化

完整可运行基础代码示例

python
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI(title="Beginner Demo")

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

@app.get("/ping")
def ping():
    return {"message": "pong"}

@app.get("/items/{item_id}")
def get_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

@app.post("/items")
def create_item(item: Item):
    return {"item": item, "status": "created"}

2.3 基础组件使用

2.3.1 FastAPI 类创建

python
from fastapi import FastAPI

app = FastAPI(
    title="My API",
    description="FastAPI learning project",
    version="1.0.0"
)

参数说明

  • title:接口文档标题
  • description:项目描述
  • version:版本号

2.3.2 路由定义(GET/POST)

python
@app.get("/hello")
def hello():
    return {"msg": "hello"}

@app.post("/echo")
def echo(data: dict):
    return {"you_sent": data}

2.3.3 路径参数与查询参数

python
@app.get("/users/{user_id}")
def get_user(user_id: int, active: bool = True):
    return {"user_id": user_id, "active": active}

2.3.4 简单响应返回

python
@app.get("/status")
def status():
    return {"ok": True}

2.4 新手常见误区与避坑

  • 路由冲突/users/me/users/{id} 顺序不当
  • 参数类型不匹配:传字符串给 int 参数会 422
  • Uvicorn 启动失败main:app 模块名/实例名写错
  • 文档访问异常:可能是自定义 docs_url 关闭了
  • 依赖版本冲突:建议固定 requirements 版本

三、核心功能与基础技巧:请求处理、响应处理、文档优化、错误处理

3.1 请求处理进阶

3.1.1 请求体与 Pydantic 模型

python
from pydantic import BaseModel, Field

class ProductIn(BaseModel):
    name: str = Field(..., min_length=2, max_length=30)
    price: float = Field(..., gt=0)
    tags: list[str] = []

@app.post("/products")
def create_product(data: ProductIn):
    return {"data": data}

参数说明

  • Field(..., gt=0):必须大于 0
  • min_length/max_length:字符串长度约束

3.1.2 表单请求

python
from fastapi import Form

@app.post("/login-form")
def login_form(username: str = Form(...), password: str = Form(...)):
    return {"username": username, "login": True}

3.1.3 文件上传

python
from fastapi import UploadFile, File

@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):
    content = await file.read()
    return {"filename": file.filename, "size": len(content)}
python
from fastapi import Header, Cookie

@app.get("/meta")
def read_meta(user_agent: str | None = Header(None), session_id: str | None = Cookie(None)):
    return {"user_agent": user_agent, "session_id": session_id}

3.2 响应处理进阶

3.2.1 响应模型定义

python
from pydantic import BaseModel

class UserOut(BaseModel):
    id: int
    name: str

@app.get("/users/{user_id}", response_model=UserOut)
def user_detail(user_id: int):
    return {"id": user_id, "name": "Tom", "password": "hidden"}  # password 会被过滤

3.2.2 状态码与响应头

python
from fastapi import Response, status

@app.post("/created", status_code=status.HTTP_201_CREATED)
def created(response: Response):
    response.headers["X-Trace-Id"] = "trace-demo-001"
    return {"message": "created"}

3.2.3 JSON / HTML / 文件响应

python
from fastapi.responses import JSONResponse, HTMLResponse, FileResponse

@app.get("/json")
def json_resp():
    return JSONResponse(content={"ok": True}, status_code=200)

@app.get("/html", response_class=HTMLResponse)
def html_resp():
    return "<h1>Hello FastAPI</h1>"

@app.get("/download")
def download():
    return FileResponse("README.md", filename="README.md")

3.3 接口文档优化

python
app = FastAPI(
    title="Order API",
    description="订单系统接口文档",
    version="1.2.0",
    docs_url="/docs",
    redoc_url="/redoc",
)

@app.get("/orders/{order_id}", tags=["orders"], summary="查询订单", description="根据订单ID查询订单详情")
def get_order(order_id: int):
    return {"order_id": order_id}

优化要点

  • tags:接口分组
  • summary/description:提高可读性
  • response_model:明确返回结构

3.4 基础错误处理

3.4.1 抛出 HTTP 异常

python
from fastapi import HTTPException

@app.get("/items/{item_id}")
def get_item(item_id: int):
    if item_id <= 0:
        raise HTTPException(status_code=400, detail="item_id must be > 0")
    return {"item_id": item_id}

3.4.2 自定义异常处理

python
from fastapi import Request
from fastapi.responses import JSONResponse

class BizError(Exception):
    def __init__(self, code: int, message: str):
        self.code = code
        self.message = message

@app.exception_handler(BizError)
async def biz_error_handler(request: Request, exc: BizError):
    return JSONResponse(status_code=400, content={"code": exc.code, "message": exc.message})

四、进阶技巧:依赖注入、认证授权、异步编程、数据验证

4.1 依赖注入(核心)

4.1.1 基础依赖

python
from fastapi import Depends

def common_query(q: str | None = None, limit: int = 10):
    return {"q": q, "limit": limit}

@app.get("/search")
def search(params: dict = Depends(common_query)):
    return params

4.1.2 路径/查询/请求体依赖链

python
from pydantic import BaseModel

class QueryBody(BaseModel):
    keyword: str

def auth_dep(token: str = Header(...)):
    if token != "demo-token":
        raise HTTPException(status_code=401, detail="invalid token")
    return {"user_id": 1}

@app.post("/secure-search")
def secure_search(body: QueryBody, user=Depends(auth_dep)):
    return {"user": user, "keyword": body.keyword}

4.1.3 可调用类依赖

python
class Pager:
    def __init__(self, default_size: int = 20):
        self.default_size = default_size

    def __call__(self, page: int = 1, size: int | None = None):
        return {"page": page, "size": size or self.default_size}

pager = Pager(default_size=15)

@app.get("/list")
def list_items(p=Depends(pager)):
    return p

4.2 身份认证与授权

4.2.1 OAuth2 + JWT(简化示例)

python
from datetime import datetime, timedelta
from jose import jwt

SECRET_KEY = "replace-with-env-secret"
ALGORITHM = "HS256"

def create_access_token(data: dict, expire_minutes: int = 30):
    payload = data.copy()
    payload["exp"] = datetime.utcnow() + timedelta(minutes=expire_minutes)
    return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)

4.2.2 API Key 认证

python
from fastapi.security import APIKeyHeader

api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)

def api_key_auth(api_key: str | None = Depends(api_key_header)):
    if api_key != "my-secret-key":
        raise HTTPException(status_code=403, detail="forbidden")
    return True

@app.get("/protected", dependencies=[Depends(api_key_auth)])
def protected():
    return {"ok": True}

4.3 异步编程

python
import asyncio

@app.get("/async-demo")
async def async_demo():
    await asyncio.sleep(0.1)
    return {"message": "async done"}

场景说明

  • I/O 密集任务(数据库、网络请求)优先 async
  • CPU 密集任务建议丢给任务队列或进程池

4.4 数据验证与序列化(Pydantic 进阶)

python
from pydantic import BaseModel, field_validator

class UserCreate(BaseModel):
    username: str
    age: int

    @field_validator("age")
    @classmethod
    def validate_age(cls, v: int):
        if v < 0 or v > 120:
            raise ValueError("age must be between 0 and 120")
        return v

嵌套模型示例

python
class Address(BaseModel):
    city: str
    street: str

class UserProfile(BaseModel):
    name: str
    address: Address

五、实战场景:RESTful、数据库集成、前后端分离、异步任务、部署监控

5.1 基础 RESTful API 开发(CRUD)

python
from fastapi import APIRouter

router = APIRouter(prefix="/books", tags=["books"])
fake_db: dict[int, dict] = {}

@router.post("/")
def create_book(book_id: int, title: str):
    fake_db[book_id] = {"id": book_id, "title": title}
    return fake_db[book_id]

@router.get("/{book_id}")
def get_book(book_id: int):
    return fake_db.get(book_id, {"error": "not found"})

@router.put("/{book_id}")
def update_book(book_id: int, title: str):
    if book_id not in fake_db:
        raise HTTPException(status_code=404, detail="not found")
    fake_db[book_id]["title"] = title
    return fake_db[book_id]

@router.delete("/{book_id}")
def delete_book(book_id: int):
    fake_db.pop(book_id, None)
    return {"deleted": True}

app.include_router(router)

5.2 数据库集成(FastAPI + SQLAlchemy + SQLite)

python
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker, Session

DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)
Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)

Base.metadata.create_all(bind=engine)

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.post("/db/users")
def create_db_user(name: str, db: Session = Depends(get_db)):
    user = User(name=name)
    db.add(user)
    db.commit()
    db.refresh(user)
    return {"id": user.id, "name": user.name}

5.3 前后端分离接口开发(CORS + 统一响应)

python
from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173", "http://127.0.0.1:5173"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

def success(data, message="ok"):
    return {"code": 0, "message": message, "data": data}

@app.get("/frontend-demo")
def frontend_demo():
    return success({"name": "fastapi"})

5.4 异步任务与定时任务

5.4.1 BackgroundTasks

python
from fastapi import BackgroundTasks

def write_log(msg: str):
    with open("app.log", "a", encoding="utf-8") as f:
        f.write(msg + "\n")

@app.post("/notify")
def notify(background_tasks: BackgroundTasks, email: str):
    background_tasks.add_task(write_log, f"send email to {email}")
    return {"message": "task submitted"}

5.4.2 Celery 集成(示意)

python
# pip install celery redis
# celery_app.py 中定义任务,然后 FastAPI 接口触发 delay()

5.5 接口部署与监控

Uvicorn 运行

bash
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 2

Gunicorn + UvicornWorker(Linux)

bash
gunicorn main:app -k uvicorn.workers.UvicornWorker -w 4 -b 0.0.0.0:8000

日志建议

  • 记录 trace_id、path、status_code、latency
  • 区分 access log 与 error log

六、高级进阶:微服务、性能优化、自定义组件、部署上线

6.1 微服务开发

核心说明

  • 按领域拆服务:用户服务、订单服务、支付服务
  • 服务间通信:HTTP/gRPC/消息队列
  • API 网关:统一鉴权、限流、路由

简单通信示例

python
import httpx

@app.get("/call-user-service")
async def call_user_service(user_id: int):
    async with httpx.AsyncClient(timeout=5) as client:
        resp = await client.get(f"http://user-service:8001/users/{user_id}")
    return resp.json()

6.2 性能优化

  • 接口缓存:Redis 缓存热点数据
  • SQL 优化:索引、分页、避免 N+1
  • 异步并发:I/O 任务用 async
  • 连接池:数据库连接池参数调优

缓存示例(伪代码)

python
# if redis.get(cache_key): return cached_data
# data = query_db()
# redis.setex(cache_key, 60, data_json)

6.3 自定义组件开发

6.3.1 自定义中间件

python
import time
from starlette.middleware.base import BaseHTTPMiddleware

class TimingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        start = time.time()
        response = await call_next(request)
        response.headers["X-Process-Time"] = f"{time.time() - start:.4f}s"
        return response

app.add_middleware(TimingMiddleware)

6.3.2 自定义响应类(示意)

python
from fastapi.responses import JSONResponse

class BizJSONResponse(JSONResponse):
    def render(self, content):
        wrapped = {"code": 0, "message": "ok", "data": content}
        return super().render(wrapped)

6.4 部署与上线(Docker + Nginx + HTTPS)

Dockerfile 示例

dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Nginx 反向代理示意

nginx
server {
    listen 80;
    server_name api.example.com;
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

七、核心工具与资源:参数手册、模板库、学习资源

7.1 FastAPI 常用参数手册

FastAPI(...) 常用参数

  • title:文档标题
  • description:文档描述
  • version:版本号
  • docs_url:Swagger 路径
  • redoc_url:ReDoc 路径

路由装饰器常用参数

  • response_model:响应模型
  • status_code:状态码
  • tags:接口分组
  • summary / description:接口说明
  • dependencies:全局依赖注入

参数声明函数

  • Path(...):路径参数约束
  • Query(...):查询参数约束
  • Body(...):请求体约束
  • Header(...) / Cookie(...):请求头/Cookie

7.2 优质实战模板

模板1:统一响应

python
def resp_ok(data=None, msg="ok"):
    return {"code": 0, "message": msg, "data": data}

模板2:分页参数依赖

python
from fastapi import Query

def pagination(page: int = Query(1, ge=1), size: int = Query(10, ge=1, le=100)):
    return {"page": page, "size": size}

模板3:健康检查接口

python
@app.get("/health")
def health():
    return {"status": "UP"}

7.3 学习资源推荐


八、常见问题与避坑指南:高频问题修复与高级避坑

8.1 高频问题修复

问题1:接口 422 参数校验失败

错误代码

python
@app.get("/demo")
def demo(age: int):
    return {"age": age}
# 调用 /demo?age=abc 会报 422

修正思路

  • 传正确类型
  • 或将参数改为 str 并自行转换

问题2:异步任务不执行

错误原因

  • 进程提前退出
  • 后台任务函数抛错未记录

修正建议

  • 给任务加异常日志
  • 关键任务使用 Celery 而非 BackgroundTasks

问题3:数据库连接失败

常见原因

  • 连接串写错
  • 数据库未启动
  • 驱动未安装(如 pymysql, psycopg2-binary

问题4:跨域问题(CORS)

修正代码

python
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 生产建议填具体域名
    allow_methods=["*"],
    allow_headers=["*"],
)

问题5:认证失败(401/403)

原因说明

  • token 过期
  • 签名密钥不一致
  • 请求头格式错误(Authorization: Bearer <token>

8.2 高级避坑技巧

  • 避免接口冗余:按资源维度设计路由,统一命名规范
  • 优化响应速度:减少同步 I/O,增加缓存层
  • 降低服务器负载:合理 worker 数,限制大请求体
  • 高并发适配:连接池、限流、熔断、异步队列

九、实战案例汇总(3-5个完整案例)

案例1:图书管理 RESTful API

需求分析:实现图书增删改查。
环境搭建:FastAPI + Uvicorn。
接口设计/books + CRUD。
部署测试:通过 Swagger UI 调试并验证响应。

案例2:用户认证中心(JWT)

需求分析:登录后发 token,受保护接口校验 token。
核心实现/login + create_access_token + 依赖注入鉴权。
效果说明:可用于后台管理系统鉴权。

案例3:电商订单服务(数据库持久化)

需求分析:订单创建、查询、更新。
技术栈:FastAPI + SQLAlchemy + SQLite/MySQL。
优化点:分页查询、索引优化、统一错误处理。

案例4:前后端分离接口网关

需求分析:提供统一接口层,适配前端应用。
关键功能:CORS、统一响应、错误码规范。
部署方式:Nginx + Uvicorn/Gunicorn。

案例5:异步通知服务

需求分析:下单后异步发送通知,不阻塞主流程。
实现方式:BackgroundTasks(轻量)或 Celery(生产)。
效果说明:显著降低同步接口耗时。


十、运行环境与依赖清单

10.1 推荐环境

  • Python 3.9+
  • fastapi 0.110+
  • uvicorn 0.27+
  • pydantic 2.x
  • sqlalchemy 2.x

10.2 一键安装命令

bash
pip install fastapi uvicorn pydantic sqlalchemy python-multipart python-jose[cryptography] passlib[bcrypt]

10.3 启动命令

bash
uvicorn main:app --reload

十一、总结

关键结论

  • FastAPI 的核心优势是:性能高 + 开发快 + 文档自动化 + 类型安全
  • 工程化落地关键是:规范接口、统一错误处理、完善认证、可观测与可部署
  • 进阶路线建议:先 CRUD -> 再认证与数据库 -> 最后异步与微服务部署