FastAPI 响应类型完全指南:从 JSON 到流式响应、异常处理与输出模型
2026/6/4 21:27:58 网站建设 项目流程

【学习记录】FastAPI 响应类型完全指南:从 JSON 到流式响应、异常处理与输出模型

在构建 Web API 时,不仅需要接收参数,还需要灵活控制返回给客户端的响应格式。FastAPI 提供了丰富的响应类型支持,包括 JSON、HTML、纯文本、文件、流式数据、重定向等,还可以通过response_model自动验证和序列化输出,并通过HTTPException规范错误响应。本文系统讲解 FastAPI 中所有常用的响应类型及其使用场景,提供完整可运行的代码示例,助你构建专业、健壮的 API。


📌 目录

  1. JSONResponse(默认行为)
  2. HTMLResponse:返回 HTML 页面
  3. PlainTextResponse:纯文本响应
  4. FileResponse:文件下载与预览
  5. StreamingResponse:流式传输大文件或实时数据
  6. RedirectResponse:重定向
  7. 在装饰器中指定响应类型(response_class
  8. 直接返回响应对象
  9. 自定义输出模型:response_model自动验证与文档生成
  10. 异常响应处理:HTTPException与自定义异常处理器
  11. 完整可运行示例
  12. 总结与最佳实践

一、JSONResponse(默认行为)

FastAPI 默认使用JSONResponse将返回的字典或 Pydantic 模型自动转换为 JSON 格式,并设置Content-Type: application/json。你无需显式导入,直接返回 Python 字典即可。

fromfastapiimportFastAPI app=FastAPI()@app.get("/json-default")defjson_default():return{"message":"This is automatically converted to JSONResponse"}

也可以显式使用JSONResponse,以便自定义状态码或其他响应头:

fromfastapi.responsesimportJSONResponse@app.get("/json-explicit")defjson_explicit():returnJSONResponse(content={"message":"Explicit JSONResponse"},status_code=201)

二、HTMLResponse:返回 HTML 页面

使用HTMLResponse可以返回 HTML 内容,浏览器会将其渲染为网页。

fromfastapi.responsesimportHTMLResponse@app.get("/html",response_class=HTMLResponse)defhtml_response():html_content=""" <html> <head><title>FastAPI HTML</title></head> <body> <h1>Hello, FastAPI!</h1> <p>This is an HTML response.</p> </body> </html> """returnhtml_content

三、PlainTextResponse:纯文本响应

当需要返回纯文本(如日志、配置内容)时,使用PlainTextResponse,避免框架自动添加额外格式。

fromfastapi.responsesimportPlainTextResponse@app.get("/text",response_class=PlainTextResponse)deftext_response():return"This is plain text response."

四、FileResponse:文件下载与预览

FileResponse可以返回服务器上的文件,自动推断Content-Type(如image/jpegapplication/pdf),支持设置下载文件名。

fromfastapi.responsesimportFileResponse@app.get("/file")deffile_response():# 假设当前目录下存在 example.pdfreturnFileResponse("example.pdf",filename="document.pdf",media_type="application/pdf")
  • filename:建议浏览器下载时的文件名。
  • media_type:可手动指定,不指定则自动推断。

五、StreamingResponse:流式传输大文件或实时数据

当文件很大或需要边生成边发送数据(如实时日志、视频流、AI 生成流)时,使用StreamingResponse。它接受一个异步生成器或迭代器,逐块发送数据。

fromfastapi.responsesimportStreamingResponseimportasyncioasyncdefdata_generator():foriinrange(5):yieldf"Chunk{i}\n".encode()awaitasyncio.sleep(1)@app.get("/stream")asyncdefstreaming_response():returnStreamingResponse(data_generator(),media_type="text/plain")

六、RedirectResponse:重定向

RedirectResponse用于将客户端重定向到另一个 URL,支持永久(301)或临时(302)重定向。

fromfastapi.responsesimportRedirectResponse@app.get("/redirect")defredirect():returnRedirectResponse(url="https://fastapi.tiangolo.com",status_code=302)

七、在装饰器中指定响应类型(response_class

无需在函数内部返回响应对象,直接在装饰器中使用response_class参数即可指定该端点的默认响应类型。函数体内返回对应格式的内容(字符串、字典等),FastAPI 会自动封装。

@app.get("/html-decorator",response_class=HTMLResponse)defhtml_decorator():# 直接返回 HTML 字符串,FastAPI 会用 HTMLResponse 包装return"<h1>Title</h1><p>This HTML is from decorator.</p>"

八、直接返回响应对象

在路径操作函数中直接返回Response子类的实例,可以完全控制响应内容、状态码和头部。

@app.get("/return-obj")defreturn_response_object():returnHTMLResponse(content="<h2>Returned as HTMLResponse object</h2>",status_code=200)

九、自定义输出模型:response_model自动验证与文档生成

通过response_model参数指定一个 Pydantic 模型,FastAPI 会:

  • 自动验证返回值是否符合模型定义(类型、必填字段等)
  • 序列化模型实例为 JSON
  • 在 OpenAPI 文档中生成精确的响应 schema
frompydanticimportBaseModelfromtypingimportListclassItem(BaseModel):name:strprice:float@app.get("/items/{item_id}",response_model=Item)defget_item(item_id:int):# 实际可能从数据库查询returnItem(name="Apple",price=1.99)@app.get("/items",response_model=List[Item])deflist_items():return[Item(name="Apple",price=1.99),Item(name="Orange",price=2.49)]

注意:返回的数据会自动排除模型中未定义的字段(如内部字段_id),起到输出过滤作用。


十、异常响应处理:HTTPException与自定义异常处理器

10.1 抛出标准 HTTP 异常

使用HTTPException可以返回标准 HTTP 错误码和错误信息,FastAPI 会自动生成对应的 JSON 响应。

fromfastapiimportHTTPException@app.get("/secure/{code}")defsecure_endpoint(code:int):ifcode!=42:raiseHTTPException(status_code=403,detail="Invalid access code")return{"message":"Welcome"}

10.2 自定义异常处理器

可以覆盖默认的异常响应格式,例如统一错误返回格式。

fromfastapiimportRequestfromfastapi.responsesimportJSONResponse@app.exception_handler(403)asyncdefforbidden_exception_handler(request:Request,exc:HTTPException):returnJSONResponse(status_code=403,content={"error":"Access forbidden","detail":exc.detail})

十一、完整可运行示例

将上述所有片段整合到一个文件中(main.py),启动服务后即可测试。

fromfastapiimportFastAPI,HTTPExceptionfromfastapi.responsesimport(JSONResponse,HTMLResponse,PlainTextResponse,FileResponse,StreamingResponse,RedirectResponse)frompydanticimportBaseModelfromtypingimportListimportasyncio app=FastAPI(title="响应类型演示",description="展示各种响应方式")# 1. JSONResponse(默认)@app.get("/json-default")defjson_default():return{"message":"JSON default"}# 2. HTMLResponse@app.get("/html",response_class=HTMLResponse)defhtml_response():return"<html><body><h1>HTML</h1></body></html>"# 3. PlainTextResponse@app.get("/text",response_class=PlainTextResponse)deftext_response():return"Plain text"# 4. FileResponse(需要存在 example.pdf)@app.get("/file")deffile_response():returnFileResponse("example.pdf",filename="doc.pdf")# 5. StreamingResponseasyncdefstream_gen():foriinrange(3):yieldf"data:{i}\n".encode()awaitasyncio.sleep(0.5)@app.get("/stream")asyncdefstreaming():returnStreamingResponse(stream_gen(),media_type="text/plain")# 6. RedirectResponse@app.get("/redirect")defredirect():returnRedirectResponse("https://fastapi.tiangolo.com")# 7. 装饰器指定响应类型(已由 html 端点展示)# 8. 直接返回响应对象@app.get("/return-obj")defreturn_obj():returnHTMLResponse("<h2>Direct Response Object</h2>")# 9. response_model 自定义输出格式classItem(BaseModel):name:strprice:float@app.get("/items/{item_id}",response_model=Item)defget_item(item_id:int):returnItem(name="Apple",price=1.99)@app.get("/items",response_model=List[Item])deflist_items():return[Item(name="Apple",price=1.99),Item(name="Orange",price=2.49)]# 10. HTTPException@app.get("/secure/{code}")defsecure(code:int):ifcode!=42:raiseHTTPException(status_code=403,detail="Invalid code")return{"message":"OK"}# 自定义异常处理器(可选)@app.exception_handler(403)asyncdefcustom_403(request,exc):returnJSONResponse(status_code=403,content={"detail":"Forbidden custom message"})

启动服务

uvicorn main:app--reload

访问测试

  • http://127.0.0.1:8000/json-default
  • http://127.0.0.1:8000/html
  • http://127.0.0.1:8000/text
  • http://127.0.0.1:8000/file(需文件存在)
  • http://127.0.0.1:8000/stream
  • http://127.0.0.1:8000/redirect
  • http://127.0.0.1:8000/return-obj
  • http://127.0.0.1:8000/items/1
  • http://127.0.0.1:8000/items
  • http://127.0.0.1:8000/secure/123(返回 403)

十二、总结与最佳实践

响应类型适用场景关键点
JSONResponseREST API 默认格式直接返回字典或 Pydantic 模型
HTMLResponse返回网页、富文本内容可使用response_class=HTMLResponse
PlainTextResponse纯文本(日志、配置)避免额外格式包装
FileResponse文件下载、图片预览自动识别Content-Type
StreamingResponse大文件、实时流、SSE使用异步生成器
RedirectResponse跳转到其他 URL可设置永久/临时重定向
response_model输出格式约束、自动文档推荐用于所有公开 API
HTTPException统一错误响应可自定义异常处理器

核心建议

  • ✅ 默认使用 JSONResponse 返回结构化数据。
  • ✅ 为所有公开端点声明response_model,即使返回字典也建议定义模型。
  • ✅ 对于大文件或流式数据,优先使用StreamingResponse避免内存溢出。
  • ✅ 错误处理统一使用HTTPException,并考虑全局异常处理器。
  • ✅ 利用response_class简化装饰器代码,使函数体更简洁。

通过灵活运用 FastAPI 的响应类型,你可以轻松构建出功能丰富、文档完善、健壮可维护的 Web API。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询