FEATURED · 精选文章

FastAPI 响应格式类型全解析:从 JSON 到流式文件

发布时间 / 2026/8/7 17:24:14
来源 / 创域科博编辑部
栏目 / 资讯中心
FastAPI 响应格式类型全解析:从 JSON 到流式文件 FastAPI 响应格式类型全解析从 JSON 到流式文件FastAPI 的一个核心设计原则是“选择正确的工具做正确的事”。当你需要返回数据时它绝不仅限于一种 JSON 格式而是内置了丰富且开箱即用的响应类型让开发者能够针对不同场景返回最合适的内容。这篇文章将深入剖析 FastAPI 中各种响应格式类型包括它们的使用方法、适用场景以及如何灵活地切换和控制这些类型。1. 默认王者JSONResponseFastAPI 的路径操作函数默认返回 JSON 格式。当你直接返回字典、列表或 Pydantic 模型时FastAPI 会自动将其转换为 JSON 并放入一个JSONResponse对象中。pythonfrom fastapi import FastAPI from pydantic import BaseModel app FastAPI() class Item(BaseModel): name: str price: float app.get(/item) def get_item(): return {name: Widget, price: 9.99}访问/item得到json{name: Widget, price: 9.99}适用场景绝大多数 API 接口前后端分离的数据交互。你可以通过response_model进一步控制输出字段但底层响应类型依然是JSONResponse。2. 声明式切换response_class参数每个路径操作装饰器都接受一个response_class参数用来指定返回的响应类型。这是切换响应格式最直接的方式。pythonfrom fastapi.responses import HTMLResponse app.get(/page, response_classHTMLResponse) def get_page(): return h1Hello World/h1一旦指定了response_classFastAPI 就会把你返回的字符串或生成器作为该类型响应的 body 内容。下面我们依次介绍各种内置响应类。3. HTML 响应HTMLResponse当你需要返回 HTML 页面例如服务端渲染或简单的静态页面时使用HTMLResponse。pythonfrom fastapi.responses import HTMLResponse app.get(/index, response_classHTMLResponse) def index(): html_content html headtitleFastAPI/title/head bodyh1Welcome to FastAPI/h1/body /html return html_content适用场景返回完整的 HTML 页面、富文本片段或结合模板引擎如 Jinja2渲染后的字符串。如果直接返回str而不指定HTMLResponseFastAPI 会将其视为 JSON 字符串即返回h1.../h1带上引号导致前端无法正确渲染。4. 纯文本响应PlainTextResponsePlainTextResponse用于返回纯文本内容它设置了Content-Type: text/plain。pythonfrom fastapi.responses import PlainTextResponse app.get(/robots.txt, response_classPlainTextResponse) def robots(): return User-agent: *\nDisallow: /admin适用场景返回配置文件、日志片段、或者任何需要避免浏览器解析 HTML 的文本。5. 文件下载FileResponseFileResponse专为发送文件而设计它支持异步文件流、断点续传Range 请求并可自动检测 MIME 类型。pythonfrom fastapi.responses import FileResponse app.get(/download-report) def download_report(): file_path /app/reports/annual.pdf return FileResponse( pathfile_path, filename2024-annual-report.pdf, # 下载时显示的文件名 media_typeapplication/pdf # 可选不指定则自动推断 )优势内存占用低直接利用操作系统级别的文件发送能力尤其适合大文件。适用场景文件下载、图片/视频展示、静态资源提供。6. 流式响应StreamingResponse当数据量很大或需实时生成时使用StreamingResponse可以边生成边发送避免撑爆服务器内存。6.1 生成大型 CSV 文件pythonfrom fastapi.responses import StreamingResponse def iter_csv_rows(): yield id,name,email\n for i in range(100000): yield f{i},user{i},user{i}example.com\n app.get(/export-csv) def export_csv(): return StreamingResponse( iter_csv_rows(), media_typetext/csv, headers{Content-Disposition: attachment; filenameusers.csv} )6.2 代理远程视频流pythonimport httpx from fastapi.responses import StreamingResponse async def remote_video_stream(): async with httpx.AsyncClient() as client: async with client.stream(GET, https://example.com/video.mp4) as r: async for chunk in r.aiter_bytes(): yield chunk app.get(/proxy-video) async def proxy_video(): return StreamingResponse( remote_video_stream(), media_typevideo/mp4 )适用场景实时日志推送、大文件导出、视频/音频流、代理转发等。注意如果数据源是同步生成器FastAPI 会将其放在线程池中运行以避免阻塞事件循环。7. 重定向RedirectResponseRedirectResponse用于实现 URL 跳转默认状态码 307临时重定向也可指定其他 3xx 状态码。pythonfrom fastapi.responses import RedirectResponse app.get(/old-url) def old_url(): return RedirectResponse(url/new-url, status_code301) app.get(/new-url) def new_url(): return {message: You have been redirected}适用场景接口迁移、OAuth 回调、表单提交后的重定向PRG 模式。8. 原始响应Response 基类当你需要返回非文本内容如 JPEG 图片的二进制数据或自定义 Content-Type 时可以直接使用Response基类。pythonfrom fastapi.responses import Response app.get(/image) def get_image(): with open(logo.png, rb) as f: image_bytes f.read() return Response(contentimage_bytes, media_typeimage/png)你也可以用它返回 XML 或任何自定义格式的数据pythonapp.get(/data.xml, response_classResponse) def get_xml(): xml ?xml version1.0?dataid1/id/data return Response(contentxml, media_typeapplication/xml)9. 自定义响应类封装与扩展所有内置响应类都继承自starlette.responses.Response你可以轻松扩展它们来实现统一响应结构或修改序列化行为。9.1 统一 API 响应格式很多团队喜欢用{code: 0, msg: success, data: ...}包裹所有返回数据我们可以通过自定义JSONResponse实现pythonfrom fastapi.responses import JSONResponse from typing import Any class ApiResponse(JSONResponse): def render(self, content: Any) - bytes: # 避免双重包裹 if isinstance(content, dict) and code in content: return super().render(content) wrapped { code: self.status_code if self.status_code 400 else -1, msg: success if self.status_code 400 else error, data: content, } return super().render(wrapped) # 设为全局默认响应类 app FastAPI(default_response_classApiResponse) app.get(/item) def get_item(): return {name: Widget} # 自动包裹为统一格式9.2 自定义 JSON 序列化如果你需要全局更改datetime的格式或让 JSON 支持更多自定义类型可以重写render方法pythonimport json from datetime import datetime class CustomJSONResponse(JSONResponse): def render(self, content: Any) - bytes: return json.dumps( content, ensure_asciiFalse, indent2, defaultstr # 所有不可序列化对象转为 str ).encode(utf-8)然后通过response_classCustomJSONResponse或在应用层面设置。10. 总结与选择指南FastAPI 提供了从常见到极客的响应格式类型选择它们的原则很简单场景响应类返回 JSON 数据API 主体JSONResponse默认返回 HTML 页面HTMLResponse返回纯文本PlainTextResponse文件下载支持断点续传FileResponse流式传输大数据或实时数据StreamingResponseURL 重定向RedirectResponse返回二进制或非标准格式Response基类自定义序列化或统一数据结构继承JSONResponse你可以通过response_class静态声明也可以直接返回对应响应类的实例后者还允许在函数内动态设置状态码、Header 等。这种灵活性使得 FastAPI 在处理各种响应格式时游刃有余。掌握这些响应格式类型后你就能在 REST API、微服务、文件服务甚至实时数据推送等场景中游刃有余彻底告别“只能返回 JSON”的尴尬写出既专业又高性能的 Web 接口。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻