Python FastAPI 路由完全教程:从基础到模块化实战
FastAPI 的路由是处理 HTTP 请求的核心机制,支持单文件简单路由和多文件模块化路由,能灵活适配从小型接口到大型应用的各类场景。本教程将结合基础用法、模块化实战、高级特性和最佳实践,帮你彻底掌握 FastAPI 路由的使用。
一、路由核心概念
路由是 FastAPI 中连接客户端请求与服务端处理逻辑的桥梁,负责将特定 HTTP 方法(GET/POST 等)和 URL 路径映射到对应的处理函数(Route Handler)。
- 核心作用:接收客户端请求、分发到对应处理逻辑、返回响应结果。
- 核心组件:FastAPI 实例(单文件路由)或 APIRouter 实例(模块化路由)、路径装饰器(如 @app.get)、处理函数。
- 优势:支持自动路径解析、请求参数校验、API 文档自动生成,且保持代码结构清晰。
二、基础路由用法(单文件)
单文件路由适用于简单应用或小型接口,直接通过 FastAPI 实例定义路由,快速高效。
1. 最小示例
from fastapi import FastAPI
# 创建 FastAPI 应用实例
app = FastAPI()
# 定义 GET 方法的根路由,处理函数返回字典(自动转为 JSON 响应)
@app.get('/')
async def welcome() -> dict:
return {"message": "Welcome to FastAPI Router Tutorial"}
2. 运行应用
使用 uvicorn 启动服务,命令如下:
uvicorn main:app --port 8888 --reload
- main:文件名(不含 .py 后缀)。
- app:FastAPI 实例名。
- --reload:开发模式,文件修改后自动重启服务。
3. 测试路由
- 浏览器访问 http://127.0.0.1:8888,将看到 JSON 响应:{"message":"Welcome to FastAPI Router Tutorial"}。
- 访问 http://127.0.0.1:8888/docs,可查看自动生成的 API 文档,直接在线测试接口。
4. 多路径基础路由
在同一文件中可定义多个路由,适配不同功能:
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
async def welcome() -> dict:
return {"message": "Welcome to Home Page"}
# 数字相加功能路由
@app.get('/add/numbers')
def add_numbers(a: int = 1, b: int = 2) -> dict:
return {"result": a + b, "message": "Adding numbers successfully"}
# 字符串拼接功能路由
@app.get('/add/strings')
def add_strings(s1: str = "Hello", s2: str = "FastAPI") -> dict:
return {"result": s1 + " " + s2, "message": "Concatenating strings successfully"}
- 访问 http://127.0.0.1:8888/add/numbers?a=5&b=3,将返回 {"result":8,"message":"Adding numbers successfully"}。
- 路由处理函数支持类型注解,FastAPI 会自动校验参数类型并生成文档。
三、模块化路由(APIRouter)
当应用包含多个功能模块(如用户管理、订单处理)时,单文件路由会导致代码臃肿。APIRouter 可实现路由拆分,让代码结构更清晰、易维护。
1. APIRouter 核心作用
- 实现路由模块化,将不同功能的路由拆分到不同文件。
- 支持路由前缀、标签、响应模型等统一配置,减少重复代码。
- 可独立维护每个模块的路由,便于团队协作。
2. 模块化路由实战步骤
步骤 1:创建项目目录结构
fastwebprojects/
├── src/
│ ├── __init__.py
│ ├── main.py # 主应用入口
│ ├── add_router.py # 加法功能路由模块
│ └── user_router.py # 用户功能路由模块
├── Pipfile
└── Pipfile.lock
步骤 2:定义路由模块(以 add_router.py 为例)
from fastapi import APIRouter
# 创建 APIRouter 实例,配置统一前缀和标签
router = APIRouter(
prefix='/add', # 所有路由自动添加 /add 前缀
tags=['加法功能'], # API 文档中归类的标签
responses={404: {"description": "路径不存在"}} # 统一响应配置
)
# 无需重复写 /add 前缀,路径实际为 /add/numbers
@router.get('/numbers')
def add_numbers(a: int, b: int) -> dict:
return {"result": a + b, "operation": "add numbers"}
# 路径实际为 /add/strings
@router.get('/strings')
def add_strings(s1: str, s2: str) -> dict:
return {"result": s1 + s2, "operation": "add strings"}
步骤 3:定义第二个路由模块(user_router.py)
from fastapi import APIRouter
router = APIRouter(
prefix='/user',
tags=['用户功能'],
responses={404: {"description": "用户相关路径不存在"}}
)
@router.get('/info')
def get_user_info(user_id: int) -> dict:
return {"user_id": user_id, "username": "test_user", "email": "test@example.com"}
@router.post('/create')
def create_user(username: str, email: str) -> dict:
return {"message": "User created successfully", "username": username, "email": email}
步骤 4:主应用整合路由(main.py)
通过 include_router() 方法将子路由模块添加到主 FastAPI 实例:
from fastapi import FastAPI
from src.add_router import router as add_router # 导入加法路由
from src.user_router import router as user_router # 导入用户路由
# 创建主应用实例
app = FastAPI(title="FastAPI 模块化路由示例", version="1.0")
# 根路由
@app.get('/')
async def welcome() -> dict:
return {"message": "Welcome to Modular Router Demo", "docs_url": "/docs"}
# 整合子路由
app.include_router(add_router) # 加法功能路由,路径前缀 /add
app.include_router(user_router) # 用户功能路由,路径前缀 /user
3. 测试模块化路由
- 启动服务:uvicorn src.main:app --port 8888 --reload。
- 访问 http://127.0.0.1:8888/add/numbers?a=10&b=20,返回加法结果。
- 访问 http://127.0.0.1:8888/user/info?user_id=1001,返回用户信息。
- 查看 API 文档 http://127.0.0.1:8888/docs,可看到按标签分类的所有接口。
四、APIRouter 高级特性
1. 路由前缀与标签
- prefix:为路由模块所有路径添加统一前缀,避免重复编写(如 /add 前缀覆盖该模块所有路由)。
- tags:在 API 文档中对路由进行分类,便于查找和测试(尤其适用于多模块场景)。
2. 统一响应配置
通过 responses 参数为模块内所有路由配置统一响应,如 404、500 状态码的默认响应:
router = APIRouter(
prefix='/add',
tags=['加法功能'],
responses={
404: {"description": "请求路径不存在"},
422: {"description": "参数校验失败"},
500: {"description": "服务器内部错误"}
}
)
3. 依赖项注入
为路由模块添加统一依赖(如权限校验、日志记录),模块内所有路由都会生效:
from fastapi import APIRouter, Depends
# 定义依赖函数(示例:简单的权限校验)
def check_permission(api_key: str = None):
if api_key != "fastapi123":
raise HTTPException(status_code=403, detail="权限不足")
return True
# 为路由模块添加统一依赖
router = APIRouter(
prefix='/add',
tags=['加法功能'],
dependencies=[Depends(check_permission)]
)
4. 路径参数与查询参数
APIRouter 支持与 FastAPI 实例相同的参数定义方式,包括路径参数、查询参数、请求体等:
# 路径参数示例(如 /user/1001)
@router.get('/user/{user_id}')
def get_user_by_id(user_id: int) -> dict:
return {"user_id": user_id, "data": "user details"}
五、路由最佳实践
- 按功能拆分模块:将不同业务模块(用户、订单、商品)的路由拆分到独立文件,避免单文件代码冗余。
- 合理使用前缀和标签:前缀统一业务路径,标签优化 API 文档可读性。
- 统一响应格式:为所有路由定义一致的响应结构(如包含 code、message、data 字段),便于前端处理。
- 利用依赖注入:将通用逻辑(权限、日志、数据库连接)抽为依赖,减少重复代码。
- 版本控制:通过前缀实现 API 版本控制(如 prefix='/v1/add'),便于迭代升级。
六、常见问题解决
- 路由不生效:检查是否通过 app.include_router() 整合子路由,确保导入路径正确。
- 路径冲突:避免不同模块定义相同路径,可通过前缀区分(如 /v1/user 和 /v2/user)。
- 模块导入错误:确保项目目录结构中包含 init.py 文件,且 Python 环境能识别 src 目录。
- 文档不显示:检查 tags 参数是否正确配置,确保路由函数有类型注解(FastAPI 依赖注解生成文档)。