LOGO 首页 OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 技术文档 其他文档  
 
网站管理员

FastAPI :看懂接口与请求流程

zhenglin
2026年9月9日 15:1 本文热度 118
​只写几行 Python,浏览器里就出现了一套可以直接测试的接口文档;参数传错时,框架还会主动告诉我们错在哪里。这种“写完马上看到结果”的体验,正是 FastAPI 对新手最有吸引力的地方。

今天讲述一下 FastAPI 的自动接口文档、参数类型和 Pydantic 数据模型,并结合项目代码重点学习依赖注入与中间件的作用、执行顺序及使用场景。

一、自动接口文档与项目启动

 

截图上半部分是接口列表:蓝色 GET 用于查询,绿色 POST 用于提交。下半部分的 Schemas 来自 Pydantic 模型,点开后可以查看字段名称、类型和必填项。

from fastapi import FastAPI# 创建 FastAPI 应用对象,后续路由都注册到 app 上app = FastAPI()# 注册一个处理 GET / 请求的路由@app.get("/")async def root():    # 字典会被 FastAPI 自动转换成 JSON 响应    return {"message": "Hello World"}

app 是应用对象,@app.get("/") 声明请求方式和路径,root() 负责处理请求。修改或新增路由后,/docs 中的接口也会跟着更新

项目可以选择一种依赖管理方式启动,不要混用不同环境:

# uv:当前项目推荐uv syncuv run uvicorn main:app --reload# pippython -m venv .venv.\.venv\Scripts\Activate.ps1python -m pip install fastapi uvicornpython -m uvicorn main:app --reload# Poetrypoetry installpoetry run uvicorn main:app --reload

main:app 中,main 是模块名,app 是应用对象;--reload 会在代码变化后自动重启服务。启动成功后访问 http://127.0.0.1:8000/docs。📌


二、参数类型

FastAPI 接口常见的参数分为路径参数、查询参数和请求体参数。它们出现的位置不同,用途也不同。

路径参数

路径参数写在 URL 路径中,用来确定具体对象:

# 路径中的 {id} 会传给同名参数 id@app.get("/book/{id}")async def get_book(    # id 必须是整数,并且大于 0、小于 101    id: int = Path(..., gt=0, lt=101, description="书籍id,取值范围1-100"),):    return {"id": id, "title": f"这是第{id}本书"}
/book/3 可以通过校验;/book/abc 不是整数,/book/101 不满足 lt=101,都会返回 422。

查询参数

查询参数写在 ? 后面。分页时,page 表示当前页,pageSize 表示每页数量:

@app.get("/news/news_list")async def get_news_list(    # 不传 page 时默认为第 1 页,页码最小为 1    page: int = Query(default=1, ge=1, description="当前页码"),    # 每页默认 10 条,允许的范围是 1~60 条    pageSize: int = Query(default=10, ge=1, le=60, description="每页数量"),):    return {"page": page, "pageSize": pageSize}

请求第 2 页、每页 20 条,可以访问 /news/news_list?page=2&pageSize=20

🔎 路径参数回答“要找哪一个”,查询参数回答“要怎么查询”。

请求体参数

POST 接口通常通过请求体接收一组 JSON。user: User 表示请求体需要符合 User 类型:

@app.post("/register")async def register(user: User):    # FastAPI 已经按照 User 模型完成请求体解析和校验    return user
User 的完整定义会在下一节介绍。

常用参数约束

PathQueryField 都可以使用约束参数,FastAPI 会在执行路由前完成检查:

参数通俗解释示例
default客户端不传时采用的值default=10
...参数必须提供,没有默认值Path(...)
min_length字符串最少字符数min_length=2
max_length字符串最多字符数max_length=10
gt必须大于,不包含边界值gt=0
ge必须大于等于ge=1
lt必须小于,不包含边界值lt=101
le必须小于等于le=60
description显示在 /docs 中的说明description="当前页"

💡 g 是 greater,l 是 less,e 是 equal,缩写末尾带 e 就表示包含等号。


三、Pydantic 请求与响应模型

请求模型、响应模型和注册路由放在同一个代码块中,更容易看出它们的关系:

# 请求模型:检查客户端提交的用户名和密码class User(BaseModel):    username: str = Field(default="张三", min_length=2, max_length=10)    password: str = Field(min_length=3, max_length=20)# 响应模型:只允许接口返回 usernameclass RegisterResponse(BaseModel):    username: str# response_model 会检查并过滤路由的返回结果@app.post("/register", response_model=RegisterResponse)async def register(user: User):    # 不返回 password,避免泄露用户密码    return {"username": user.username}

user: User 用来约束请求参数的类型,response_model=RegisterResponse 用来约束响应结果的类型。

Field 的常用参数

Field 用来给模型字段补充默认值、长度、数值范围和文档说明:

参数通俗解释示例
default客户端不传时使用默认值default="张三"
default_factory调用函数生成默认值default_factory=list
min_length字符串最少字符数min_length=2
max_length字符串最多字符数max_length=10
gt数字必须大于指定值gt=0
ge数字必须大于等于指定值ge=1
lt数字必须小于指定值lt=101
le数字必须小于等于指定值le=100
description/docs 中说明字段description="用户名"
examples/docs 中提供示例值examples=["小明"]

✅ 开头截图中的 UserNewsSchemas,就是 FastAPI 根据 Pydantic 模型生成的数据结构说明。


四、依赖注入的执行过程

新闻列表和用户列表都需要分页参数。为了避免重复,可以把参数提取成公共依赖:

# 公共依赖:集中接收并校验分页参数async def common_parameters(    page: int = Query(1, ge=1),    pageSize: int = Query(10, le=60),):    # 返回值会注入使用该依赖的路由参数中    return {"page": page, "pageSize": pageSize}

需要分页的路由通过 Depends 使用它:

# Depends 会先执行 common_parameters,再把结果传给 commons@app.get("/news/news_list")async def get_news_list(commons=Depends(common_parameters)):    return commons# 多个路由可以复用同一个依赖,不必重复编写分页校验@app.get("/user/user_list")async def get_user_list(commons=Depends(common_parameters)):    return commons

Depends(common_parameters) 可以理解为:“执行当前路由前,先运行 common_parameters,再把结果交给我。”


请求 /user/user_list?page=2&pageSize=20 时,FastAPI 会:

  1. 找到目标路由,并发现其中的 Depends


  2. 调用 common_parameters,读取并校验分页参数。


  3. {"page": 2, "pageSize": 20} 放入 commons


  4. 最后执行 get_user_list 中的代码。


🧩 Depends 让公共逻辑可以复用,并由 FastAPI 自动安排执行顺序。


五、中间件的执行顺序

当前项目注册了两个 HTTP 中间件:

# 先注册的中间件位于内层@app.middleware("http")async def middleware2(request, call_next):    # call_next 之前:处理进入应用的请求    print("中间件2 start")    # 把请求交给下一层中间件或路由    response = await call_next(request)    # call_next 之后:处理路由返回的响应    print("中间件2 end")    return response# 后注册的中间件位于外层,因此请求会先进入这里@app.middleware("http")async def middleware1(request, call_next):    print("中间件1 start")    # 等待内层中间件和路由执行完成    response = await call_next(request)    print("中间件1 end")    # 将最终响应返回给客户端    return response

request 是当前请求,call_next 表示继续执行下一层,response 是后续流程返回的响应。await call_next(request) 之前处理进入的请求,之后处理返回的响应。

从代码位置看,middleware2 在上面,middleware1 在下面。后注册的 middleware1 会包在外层,所以顺序是:

middleware1 start  middleware2 start    路由执行  middleware2 endmiddleware1 end
请求进入时按代码位置自下往上,响应返回时再反向执行,这就是“洋葱模型”。

🔄 start 部分处理进入的请求,end 部分处理返回的响应。

六、中间件与依赖注入的选择方法

常见需求可以直接通过下表判断:

实际需求是否所有请求都需要路由是否需要结果选择原因
记录访问日志中间件每个请求都要执行
统计完整请求耗时中间件需要包住请求与响应全过程
给所有响应添加响应头中间件需要在路由返回后统一修改
统一处理跨域中间件属于整个应用的共同规则
维护期间拦截请求中间件可以不调用 call_next,直接返回响应
列表接口共用分页参数依赖注入只有列表需要,路由还要使用结果
部分接口读取当前用户依赖注入用户信息要交给路由继续使用
管理接口检查权限不一定依赖注入权限要求与具体路由有关
多个接口共用查询参数依赖注入可以统一校验并注入结果

🧭 关心“每个请求都要做什么”,选择中间件;关心“这个路由需要什么”,选择依赖注入。


七、结语

现在,我们已经从 /docs 看到了接口如何生成,也理清了参数类型、Pydantic、依赖注入和中间件之间的关系。


阅读原文:点击这里


该文章在 2026/9/9 15:01:32 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-9  粤公网安备44030602007207号