FastAPI 从入门到实践:构建规范的 RESTful API 服务

FastAPI 是一个现代、高性能的 Python Web 框架,基于 Starlette 和 Pydantic,专为构建 API 而生。它具备自动生成交互式文档基于 Python 类型提示的数据校验异步支持等强大特性。本文将以一个完整的示例项目为线索,从项目结构、路由管理、请求/响应模型到中间件配置,全方位讲解 FastAPI 的核心用法。

已开源到ai-demo,欢迎star~


一、项目结构概览

复制代码
fastapi/
├── main.py                  # 应用入口 & FastAPI 实例创建
├── api/
│   ├── __init__.py          # 包标识
│   └── routers.py           # API 路由定义
└── models/
    └── hello_models.py      # Pydantic 请求/响应模型

采用分层架构的思路:

  • main.py --- 应用层,负责创建 FastAPI 实例、注册中间件和路由。
  • api/ --- 接口层,存放所有路由端点。
  • models/ --- 数据层,定义 Pydantic 模型,实现请求校验与响应格式化。

二、入口文件:创建 FastAPI 应用

python 复制代码
# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from api.routers import api_router

app = FastAPI(
    title="My DeepAgents API",
    description="This is My DeepAgents API",
    version="0.1.0"
)

2.1 FastAPI 实例化参数

参数 说明
title API 文档标题(显示在 Swagger UI / ReDoc 顶部)
description API 的详细描述,支持 Markdown
version API 版本号,建议遵循语义化版本规范

这三个参数会直接反映在自动生成的 /docs/redoc 接口文档中。

2.2 启动服务

bash 复制代码
uvicorn main:app --reload
  • main:appmain.py 中的 app 实例(FastAPI 类型)。
  • --reload → 开发模式,代码修改后自动重启(生产环境请去掉该参数)。

启动后访问:

  • 交互式文档http://localhost:8000/docs
  • 备用文档http://localhost:8000/redoc

三、CORS 跨域中间件配置

python 复制代码
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000", "http://localhost:8080"],
    allow_methods=["GET", "POST"],
    allow_headers=["*"]
)

3.1 参数详解

参数 说明
allow_origins 允许跨域的前端源列表 。生产环境应指定具体域名,避免使用 ["*"]
allow_methods 允许的 HTTP 方法,如 ["GET", "POST", "PUT", "DELETE"]
allow_headers 允许的请求头,["*"] 表示允许所有

最佳实践 :开发阶段可宽松配置,上线后应严格限制 allow_origins 为明确的前端地址。


四、路由管理:APIRouter 的使用

python 复制代码
# api/routers.py
from fastapi import APIRouter

api_router = APIRouter()

APIRouter 可以将路由从主应用中解耦出来,便于大型项目的模块化管理。

4.1 注册路由到主应用

python 复制代码
# main.py
app.include_router(api_router, prefix="/api")
参数 说明
api_router 要注册的路由器实例
prefix="/api" 为该路由器下所有端点添加统一的 URL 前缀

此时,api_router 中定义的 /hello 实际访问路径变为 /api/hello


五、端点定义:GET / POST 多种传参方式

5.1 最简单的 GET 请求

python 复制代码
@api_router.get("/")
async def root():
    return {"message": "This is a FastAPI server!"}
bash 复制代码
curl http://localhost:8000/api/
# 返回: {"message": "This is a FastAPI server!"}

5.2 GET 请求返回 JSON

python 复制代码
@api_router.get("/hello", tags=["helloTag"])
async def hello():
    """
    处理 GET /api/hello 请求,返回欢迎消息。
    """
    return {"message": "Hello, World!"}
  • tags=["helloTag"] --- 在 Swagger 文档中将该端点归入 helloTag 分组,方便查找。
  • docstring 会直接显示在 Swagger 文档的端点描述中,建议养成写文档字符串的习惯。
bash 复制代码
curl http://localhost:8000/api/hello
# 返回: {"message": "Hello, World!"}

5.3 POST 请求 --- 查询参数传参

python 复制代码
@api_router.post("/hello", tags=["helloTag"])
async def hello_post(name: str = "World"):
    return {"message": f"POST response> Hello, {name}!"}

FastAPI 会自动根据函数签名推断参数来源:

  • 基础类型参数(strint 等)默认从查询参数获取。
调用方式一:URL 查询参数
bash 复制代码
curl -X POST "http://localhost:8000/api/hello?name=rick"
# 返回: {"message": "POST response> Hello, rick!"}
调用方式二:JSON Body
bash 复制代码
curl -X POST "http://localhost:8000/api/hello" \
  -H "Content-Type: application/json" \
  -d '{"name": "rick"}'
# 返回: {"message": "POST response> Hello, rick!"}
调用方式三:表单数据
bash 复制代码
curl -X POST "http://localhost:8000/api/hello" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d 'name=rick'
# 返回: {"message": "POST response> Hello, rick!"}

要点:FastAPI 对于基础类型参数,会智能地从 query、body、form 三种来源中解析,极大提升了灵活性。


六、Pydantic 模型:请求校验 & 响应格式化

这是 FastAPI 最核心的特性之一。可以把数据模型定义在 models/hello_models.py 中。

6.1 定义请求体模型

python 复制代码
# models/hello_models.py
from pydantic import BaseModel, Field

class HelloRequest(BaseModel):
    name: str = Field(default="World", description="用户名")
要素 说明
BaseModel Pydantic 基类,继承后自动获得校验、序列化能力
Field(default="World") 默认值为 "World",客户端不传则自动填充
Field(description="...") 字段说明,会显示在 Swagger 文档的 Schema 中

6.2 响应用模型

python 复制代码
class HelloResponse(BaseModel):
    message: str = Field(description="欢迎消息")

6.3 在端点中使用请求模型

python 复制代码
@api_router.post("/hello_model", tags=["helloTag"])
async def hello_post_model(request: HelloRequest):
    return {"message": f"POST Model response> Hello, {request.name}!"}
  • 参数类型标注为 HelloRequest,FastAPI 会自动:
    1. 将请求体 JSON 反序列化为 HelloRequest 实例。
    2. 校验字段类型、必填性。
    3. 校验失败时返回 422 Unprocessable Entity,并给出详细的错误信息。
正确的请求
bash 复制代码
curl -X POST "http://localhost:8000/api/hello_model" \
  -H "Content-Type: application/json" \
  -d '{"name": "rick"}'
# 返回: {"message": "POST Model response> Hello, rick!"}
不传 name(使用默认值)
bash 复制代码
curl -X POST "http://localhost:8000/api/hello_model" \
  -H "Content-Type: application/json" \
  -d '{}'
# 返回: {"message": "POST Model response> Hello, World!"}
传入错误类型(触发自动校验)
bash 复制代码
curl -X POST "http://localhost:8000/api/hello_model" \
  -H "Content-Type: application/json" \
  -d '{"name": 123}'
# 返回 422,提示 name 应为字符串

6.4 使用 response_model 控制输出

python 复制代码
@api_router.post("/hello_full_model", tags=["helloTag"],
                 response_model=HelloResponse)
async def hello_full_model(request: HelloRequest):
    return HelloResponse(
        message=f"POST Full Model response> Hello, {request.name}!"
    )
特性 说明
请求校验 request: HelloRequest 校验输入
响应过滤 response_model=HelloResponse 确保输出只包含模型定义的字段,自动屏蔽多余字段
文档生成 Swagger 文档中自动展示响应 Schema,前后端协作更高效
数据转换 即使返回 dict,FastAPI 也会按 response_model 进行转换和校验
bash 复制代码
curl -X POST "http://localhost:8000/api/hello_full_model" \
  -H "Content-Type: application/json" \
  -d '{"name": "FastAPI"}'
# 返回: {"message": "POST Full Model response> Hello, FastAPI!"}

七、完整调用示例汇总

端点 方法 路径 请求方式 curl 命令
root GET /api/ 无参 curl http://localhost:8000/api/
hello GET /api/hello 无参 curl http://localhost:8000/api/hello
hello POST /api/hello query/body/form curl -X POST "http://localhost:8000/api/hello?name=rick"
hello_model POST /api/hello_model JSON body curl -X POST "http://localhost:8000/api/hello_model" -H "Content-Type: application/json" -d '{"name":"rick"}'
hello_full_model POST /api/hello_full_model JSON body + 模型响应 curl -X POST "http://localhost:8000/api/hello_full_model" -H "Content-Type: application/json" -d '{"name":"FastAPI"}'

八、Swagger 文档实战

启动服务后访问 http://localhost:8000/docs,你会看到:

  1. 分组标签 --- 所有标注 tags=["helloTag"] 的端点归入同一组,折叠管理更清爽。
  2. 端点描述 --- 每个函数的 docstring 会作为端点说明展示。
  3. 参数说明 --- Field(description=...) 的内容会作为字段提示。
  4. 在线调试 --- 点击 "Try it out" 按钮,直接在浏览器中发送请求并查看响应。

这就是 FastAPI "文档即代码" 理念的体现 --- 你写的类型提示和 docstring,自动生成了完整的 API 文档。


九、最佳实践总结

9.1 项目结构

  • 小型项目main.py + models.py 即可。
  • 中大型项目 :按功能拆分 routers/models/services/schemas/ 等模块。

9.2 模型使用

  • 务必使用 Pydantic 模型定义请求体和响应体,避免手工解析 JSON。
  • 为每个端点单独定义请求/响应模型,保持接口契约清晰。
  • 利用 Field(description=...) 为字段添加说明,提升文档质量。

9.3 路由管理

  • 使用 APIRouter 拆分路由,按业务模块组织(如 users.pyorders.py)。
  • 统一使用 prefix 避免路径重复。

9.4 文档与注释

  • 为每个端点写清晰的 docstring,它会直接呈现在 Swagger 文档中。
  • tags 用于分组,response_model 用于声明响应格式。

9.5 生产环境注意事项

  • 去掉 --reload 参数,改用 gunicorn + uvicorn workers
  • 严格限制 allow_origins,禁止使用 ["*"]
  • 添加认证中间件(如 JWT、OAuth2)。

十、参考资料


相关推荐
RainCity1 小时前
Java Swing 自定义组件库分享(四)
java·笔记·后端
技术崽崽1 小时前
Java多线程神器——ThreadForge ,让多线程从此简单
后端
Leinwin1 小时前
OpenAI Daybreak实战指南:如何将AI安全检查嵌入你的开发流程
后端·python·flask
Ting-yu1 小时前
SpringCloud快速入门(1)---- 微服务介绍
后端·spring·spring cloud
Nicander2 小时前
Spring Boot 全局异常处理:原理与实践
spring boot·后端
若阳安好2 小时前
【备忘录】正则表达式
后端·正则表达式·restful
Cosolar2 小时前
AI Agent 的记忆战争:OpenClaw vs Hermes vs QwenPaw vs HiClaw,谁真正"记得住"?
人工智能·后端·面试
M ? A3 小时前
VuReact:Vue转React的增量编译利器
前端·vue.js·后端·react.js·面试·开源·vureact
aircrushin3 小时前
给宝宝办了个宴,朋友用trae做的工具帮了大忙
前端·后端