当前位置: 首页 > news >正文

FastAPI 基础篇:请求与响应系统详解

在Web服务中,HTTP请求(Request)和HTTP响应(Response)是客户端和服务端交互的核心机制。

客户端通过发送请求来获取资源或执行操作,服务端则根据请求内容返回相应的响应数据。

FastAPI 提供了简洁高效的RequestResponse对象,帮助开发者方便地处理传入的请求数据和构建返回的响应内容。例如:

  • 通过Request对象可以轻松获取路径参数、查询参数、请求体、请求头、Cookie 等信息。
  • 通过Response对象可以自定义状态码、响应头、响应体,并支持 JSON、HTML、纯文本、文件流等多种格式输出。

一、请求(Request)

1. 查询参数(Query Parameters)

查询参数(Query Parameters) 是指 URL 中?之后的部分。多个参数之间用&分隔

基础用法

新建一个user/router.py

fromfastapiimportAPIRouter router=APIRouter(prefix="/user",tags=["用户"])@router.get("")asyncdefget_users(user_name:str,# 必填参数,不填会报错age:int=0,# 有默认值的查询参数,不传给默认值address:str|None=None,# 可选查询参数,不传也行):user={"user_name":user_name,"age":age,"address":address}returnuser

在main.py中注册

fromuser.routerimportrouterasuser_router# 创建fastapi实例app=FastAPI()# 注册路由app.include_router(user_router)

请求测试

必填参数不传会返回错误

参数校验

FastAPI 通过QueryAnnotated为查询参数提供声明式校验能力。开发者可以直接在参数定义处配置长度限制、数值范围、正则匹配等规则,并自动生成接口文档,无需编写额外的校验代码。

在user/router.py新增一个接口

@router.get("/page")asyncdefpage_users(# 必填参数user_name:Annotated[str,Query(min_length=2,max_length=20,description="用户名,长度2~20个字符")],# 有默认值age:Annotated[int,Query(ge=0,le=150,description="年龄,范围0~150")]=18,# 可选参数address:Annotated[str|None,Query(max_length=100,description="地址")]=None,# 正则校验phone:Annotated[str|None,Query(pattern=r"^1[3-9]\d{9}$",description="手机号")]=None,# 分页参数page:Annotated[int,Query(ge=1,description="页码")]=1,size:Annotated[int,Query(ge=1,le=100,description="每页条数")]=10,):return{"user_name":user_name,"age":age,"address":address,"phone":phone,"page":page,"size":size}

在文档上也会体现对应的规则

Query 常用参数

参数作用示例
description描述信息description="年龄"
min_length最小长度min_length=2
max_length最大长度max_length=20
pattern正则表达式pattern=r"^\d+$"
ge大于等于ge=0
gt大于gt=0
le小于等于le=100
lt小于lt=100
alias参数别名alias="userName"
deprecated标记废弃deprecated=True

Pydantic 模型

对于参数较多的查询接口,推荐使用 Pydantic 模型封装 Query 参数。这样既能享受 Pydantic 的数据校验能力,又能让接口定义更加简洁清晰,特别适用于分页、筛选等复杂查询场景。

新建一个user/schemas.py

frompydanticimportBaseModel,FieldclassUserQuery(BaseModel):user_name:str|None=Field(default=None,max_length=20)age:int|None=Field(default=None,ge=0,le=150)address:str|None=Nonepage:int=Field(default=1,ge=1)size:int=Field(default=10,ge=1,le=100)

在user/router.py中新增一个测试接口

@router.get("/page2")asyncdefpage_users2(# 使用Annotated是为了告诉FastAPI:# UserQuery 的数据来源于 Query 参数而不是 Request Bodyquery:Annotated[UserQuery,Query()]):# 使用model_dump,也会对返回前的对象进行校验。returnquery.model_dump()

2. 路径参数

路径参数是 URL 路径中的动态部分,通常用于标识某个具体资源。FastAPI 会根据函数参数名称自动提取路径中的值,并进行类型转换和校验。

基础用法

@router.get("/detail/{user_id}")asyncdefget_user_detail(user_id:int):# 路径参数会根据类型注解自动转换return{"user_id":user_id}

上述接口中{user_id}就是路径参数,路径参数可以有多个:

@router.get("/users/{user_id}/orders/{order_id}")asyncdefget_user_order(user_id:int,order_id:int):return{"user_id":user_id,"order_id":order_id}

请求测试

需要的int参数,如果传字符串就会报错

使用 Path 增加校验规则

和 Query 参数类似,FastAPI 提供了Path用于声明路径参数的校验规则和元数据。

@router.get("/detail/{user_id}")asyncdefget_user_detail(user_id:Annotated[int,Path(ge=1,description="用户ID")]):return{"user_id":user_id}

一个注意点

# 这是动态路由@router.get("/users/{user_name}")asyncdefget_user(user_name:str):return{"user_name":user_name}# 这是静态路由@router.get("/users/hello")asyncdefhello():return{"msg":"hello"}

当我访问 GET /users/hello时会执行哪个函数。取决于那个函数写在前面。像上述的写法就会导致永远只会执行到动态路由,而静态路由不会执行。

所以官方推荐的是:静态路由写在前面,动态路由写在后面:

# 这是静态路由@router.get("/users/hello")asyncdefhello():return{"msg":"hello"}# 这是动态路由@router.get("/users/{user_name}")asyncdefget_user(user_name:str):return{"user_name":user_name}

3. 请求体参数(Request Body)

前面介绍的 Query 参数和 Path 参数都来自 URL, 而对于创建、修改等操作,需要传递大量结构化数据,此时通常使用请求体(Request Body)。 在 FastAPI 中,请求体通常使用Pydantic 模型定义,FastAPI 会自动完成请求数据解析 ,类型转换,参数校验 ,Swagger 文档生成 。

基础用法

在user/schemes.py中定义UserCreateRequest

classUserCreateRequest(BaseModel):# 定义请求体字段包含参数校验user_name:str=Field(min_length=2,max_length=20)age:int=Field(ge=0,le=150)

user/router.py新增接口

@router.post("")asyncdefcreate_user(request:UserCreateRequest):returnrequest.model_dump()

在文档测试

请求体与查询参数混用

@router.post("")asyncdefcreate_user(request:UserCreateRequest,notify:bool=False):return{"user":request.model_dump(),"notify":notify}

请求:

POST /user?notify=true

请求体:

{ "user_name": "Tom", "age": 18 }

嵌套对象

请求体最大的优势就是支持复杂结构。

frompydanticimportBaseModelclassAddress(BaseModel):city:strstreet:strclassUserCreateRequest(BaseModel):user_name:strage:int# 嵌套对象address:Address

请求体样例如下:

{"user_name":"Tom","age":18,"address":{"city":"Shanghai","street":"Pudong"}}

4. 表单参数

Form 参数用于接收表单提交的数据,常见于登录、注册等传统 HTML 表单场景,数据格式为 application/x-www-form-urlencoded 或 multipart/form-data。

基础用法

在auth/router.py中新增一个登陆接口

router=APIRouter(prefix="/auth",tags=["认证"])@router.post("/login")asyncdeflogin(username:str=Form(),password:str=Form()):return{"username":username}

在文档中测试可以看到

POST/auth/login Content-Type:application/x-www-form-urlencoded

请求体为:

username=admin&password=123456

Form + File 上传(UploadFile)

新增一个表单参数和文件混合的接口

@router.post("/profile")asyncdefupdate_profile(# ... 是 Python 内置的 Ellipsis 对象,FastAPI 只是借用它来表示“必填参数”,# FastAPI 全部组件都支持:Query(...),Path(...),Form(...)username:str=Form(...),age:int=Form(...),avatar:UploadFile=File(...)):return{"username":username,"age":age,"file":avatar.filename}

当表单中包含文件时, Content-Type就是:multipart/form-data

5. 请求头

HTTP 请求头用于携带元信息,比如:

  • token
  • user-agent
  • language
  • content-type

基础用法

我们继续在auth/router.py新增一个接口

@router.get("/headers")asyncdefget_headers(token:str|None=Header(default=None)):return{"token":token}

测试一下,能成功获取到token

一个注意点

Header 默认会做自动转换命名。

因为 Python 变量不能有-,FastAPI会把user_agent转成User-Agent

@router.get("/headers")asyncdefget_headers(token:str|None=Header(default=None),#可以通过Header(convert_underscores=False)关闭自动转换,#一般不这样做user_agent:str=Header()):return{"token":token,"user-agent":user_agent}

6. cookie

Cookie 是浏览器存储在客户端的小数据, 浏览器会自动保存 ,自动随请求发送。

基础用法

fromfastapiimportCookie@router.get("/cookie")asyncdefget_cookie(session_id:str|None=Cookie(default=None)):return{"session_id":session_id}

在文档上测试cookie发现传了没用。这里切换成专业的api工具测试(apifox)。

二、响应(Response)

FastAPI 默认会把你返回的 Python 数据(如字典、列表、Pydantic 模型)自动转成 JSON 并返回,不需要你手动做序列化。

如果要返回 HTML、文件或流数据,可以使用 FastAPI 提供的专门响应类型(如HTMLResponseFileResponseStreamingResponse)。

1. JSONResponse

这是FastAPI默认的响应类型:

content-type:application/json

基本用法

在src/resp/router.py中新增一个接口

fromfastapiimportAPIRouter,Queryfromstarlette.responsesimportJSONResponse router=APIRouter(prefix="/resp",tags=["响应测试"])@router.get("/json")defjson_demo():returnJSONResponse(content={"msg":"ok","code":200})

进行测试

定制Response

我们也可以对Response对象进行设置来返回具体的内容和响应头,响应码等信息。

@router.get("/json")defjson_demo():resp=JSONResponse(content={"msg":"ok","code":200},status_code=200,headers={"Content-Type":"application/json"})resp.set_cookie(key="session_id",value="abc123")returnresp

response_class

在 FastAPI 中,可以在装饰器上通过response_classstatus_code来预先定义响应类型和状态码,这样在函数内部只需要返回“原始数据”,不需要手动构造 Response,使代码更简洁。

@router.get("/json",status_code=200,response_class=JSONResponse)defjson_demo():return{"msg":"ok","code":200}

2. HTMLResponse

用于返回html网页。响应类型为:

content-type:text/html;

基础用法

@router.get("/html",response_class=HTMLResponse)defhtml_demo():return"<h1 style='color:red'>Hello FastAPI</h1>"

进行测试

3. PlainTextResponse

用于返回纯文本。响应类型为:

content-type:text/plain

基础用法

@router.get("/text")deftext_demo():returnPlainTextResponse("hello world")

进行测试

4. FileResponse

主要用于文件下载,浏览器访问会直接下载文件。响应类型为:

content-disposition:attachment;filename="my-image.png"content-type:image/png

基础用法

@router.get("/download")defdownload():returnFileResponse(# 服务器的文件path="D:/temp/1.png",# 下载的文件名filename="my-image.png")

5. StreamingResponse

流式响应:一边生成一边返回 ,避免一次性返回大量的数据

示例1

下载大文件

deffile_stream():""" 大文件分段下载不会爆内存 """withopen("bigfile.zip","rb")asf:whilechunk:=f.read(1024*1024):yieldchunk@router.get("/stream-file")defstream_file():returnStreamingResponse(file_stream())

示例2

模拟ai流式响应

defai_stream():forwordin["Hello","FastAPI","Streaming"]:yield(word+" ").encode("utf-8")time.sleep(0.5)@router.get("/ai")defai():returnStreamingResponse(ai_stream())

6. RedirectResponse

RedirectResponse 用于让接口返回一个重定向指令,使客户端自动跳转到另一个 URL。

基础用法

@router.get("/login")deflogin():# 登录成功后跳转到首页returnRedirectResponse(url="/home")

7. response_model

response_model用来定义接口“返回数据的结构”,FastAPI 会自动做过滤 + 校验 + 文档生成。

基础用法

定义接口和模型对象

classUser(BaseModel):name:strage:int@router.get("/user",response_model=User)# 最终返回的数据必须“符合 User 模型结构”defget_user():return{"name":"Tom","age":18,"password":"secret"# 会被自动过滤掉}

测试一下

对于 FastAPI 中请求与响应的基础内容,我们就先介绍到这里。关于更多 深入 FastAPI 的内容,我们下期再见👋。

http://www.gsyq.cn/news/1591141.html

相关文章:

  • 当AI遇见Web3:去中心化存储,正在重写数据世界的底层法则
  • 流处理化技术中的流计算窗口函数与状态管理
  • mathtype公式变色
  • 高速差分时钟信号的T型拓扑分支阻抗设计:从理论到工程实践
  • Hessian反序列化漏洞利用工具:原理、实现与实战指南
  • 为什么你的唤醒词模型听不出你的口音?用真人录音补了一课
  • Spring Boot Starter 自定义开发指南
  • 交叉编译python
  • 从零构建编程语言解释器:深入理解AST、环境与闭包实现
  • 2026亲测:上海专利代理公司排名
  • 如何实现Kazumi智能进度条预览:跨平台播放器核心技术深度解析
  • 做高端音响别踩这些误区!HiPlay 认证常见认知盲区全解析
  • 明日方舟素材资源库:一站式获取官方游戏资源的终极指南
  • 训练计划优化:个性化训练方案的生成算法
  • 把自己 / 球星变成“苹果风 emoji 小人“!世界杯版头像,一句话生成(附中文提示词)
  • Claude Code/AI 工具接入自定义 API Key、Base URL 与模型名的完整配置排错指南
  • 058、Zephyr RTOS内核基础:中断管理基础
  • 张量可视化实战:用厨房类比理解多维张量结构
  • 小厂前端面经
  • 2026 企业 AI 生产环境 API 聚合平台选型全解析
  • 2026年双机热备软件选型指南:从国际品牌到国产替代,一份排名帮你决策。
  • 滑动窗口解法:最短子数组长度代码解释与优化
  • 从信息收集到权限提升:一次完整的Linux服务器渗透测试实战复盘
  • 我想认真做一件小事:让孩子和家长更好地互动
  • Rademacher公式在pod2(n)精确计算中的应用与实现
  • LLaMA Factory:100+大模型统一微调平台
  • 跨境电商进入中东:客服做不好,你连第一单都接不到
  • 文档下载终极解决方案:如何绕过30+平台限制获取任意可见内容
  • 区域PACS源码,java云PACS源码,影像归档系统源码,自主产品,适合二开
  • 人工智能参与工业化精密加工的物理效率