- 最傻瓜的方式:直接返回字典(默认JSON响应)
这是你最先接触的用法。FastAPI会自动把字典、列表等转成JSON,并设置响应头Content-Type: application/json。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
# 直接返回一个字典
return {"message": "Hello World"}
访问机会得到:
{"message": "Hello World"}
- 用response_model规定输出的数据形状
response_model就像一个质检员,它会:
把你函数返回的数据转换成指定的Pydantic模型结构
过滤掉不想让客户端看到的字段(比如密码)
自动生成API文档
from pydantic import BaseModel
class UserIn(BaseModel): # 用于输入(注册)
username: str
password: str
class UserOut(BaseModel): # 用于输出(返回给客户端)
username: str
@app.post("/user", response_model=UserOut)
def create_user(user: UserIn):
# 虽然返回的是包含password的user,但response_model会把它过滤掉
return user
客户端调用后只会收到 {"username": "xxx"},password字段被自动去除。
怎么用:
把Pydantic模型写在装饰器的response_model参数里
还可以用response_model_include/response_model_exclude进一步控制显示/隐藏字段
如果不需要过滤,可以不写response_model,但写上可以提高文档质量和安全性
- 直接返回各种"封装好的响应盒子"(Response对象)
当你想控制更多细节(比如状态码、响应头、Cookie,或者返回非JSON内容)时,就要直接返回一个Response对象或其子类。这些类都在fastapi.responses里。
📦 JSONResponse ------ 手工打造JSON响应
如果你需要在返回JSON的同时设置自定义头或状态码,就可以用这个。
from fastapi.responses import JSONResponse
@app.get("/custom-json")
def custom_json():
content = {"msg": "手工打造"}
return JSONResponse(
content=content,
status_code=201, # 自定义状态码
headers={"X-Custom": "foo"} # 自定义响应头
)
📄 HTMLResponse ------ 返回网页
from fastapi.responses import HTMLResponse
@app.get("/page", response_class=HTMLResponse)
def get_page():
html = "<h1>你好</h1><p>这是HTML页面</p>"
return html
你也可以不用response_class参数,直接返回HTMLResponse实例:
return HTMLResponse(content="<h1>...</h1>", status_code=200)
✍️ PlainTextResponse ------ 纯文本
from fastapi.responses import PlainTextResponse
@app.get("/text", response_class=PlainTextResponse)
def get_text():
return "这是一段纯文本,不是HTML也不是JSON"
🔄 RedirectResponse ------ 重定向
from fastapi.responses import RedirectResponse
@app.get("/old")
def old_page():
return RedirectResponse("/new-page")
访问 /old 时,浏览器会自动跳转到/new-page。
📁 FileResponse ------ 文件下载
from fastapi.responses import FileResponse
@app.get("/download")
def download():
file_path = "example.png"
return FileResponse(
path=file_path,
filename="download-name.png", # 让浏览器看到的名字
media_type="image/png" # 可选,自动识别
)
🌊 StreamingResponse ------ 流式响应(大数据、实时输出)
适合返回很大的数据流(如AI生成内容、视频流、SSE)。
from fastapi.responses import StreamingResponse
def data_generator():
for i in range(10):
yield f"第{i}条数据\n"
@app.get("/stream")
def stream():
return StreamingResponse(data_generator(), media_type="text/plain")
- 在装饰器里设置response_class ------ 改变默认响应格式
如果你希望一个路由返回某些内容时,自动被包裹成指定的响应类(而不用在函数内手动创建响应对象),就用response_class参数。
最常见的例子:返回字符串时,默认是JSON字符串(带引号),但我们想返回HTML/纯文本。
@app.get("/auto-html", response_class=HTMLResponse)
def auto_html():
# 直接返回字符串,FastAPI会用HTMLResponse包装
return "<h1>我是自动生成的HTML</h1>"
如果不写response_class=HTMLResponse,你会看到带引号的字符串 "<h1>...</h1>",而不是被浏览器渲染的HTML。
总结:response_class相当于告诉FastAPI:"这个路由内部返回的任何数据,都用这种盒子发出去"。
- 文档中声明额外响应(不同状态码的模型)
当你希望OpenAPI文档里展示某个接口在错误状态码(如404)时返回的数据结构,可以使用responses参数。
from pydantic import BaseModel
class Message(BaseModel):
message: str
@app.get(
"/items/{item_id}",
response_model=dict,
responses={
404: {"model": Message, "description": "物品未找到"},
200: {"description": "成功返回物品数据"}
}
)
async def read_item(item_id: str):
if item_id != "123":
return JSONResponse(status_code=404, content={"message": "找不到物品"})
return {"item_id": item_id, "value": "重要资料"}
这样Swagger文档里就会清楚说明404会返回{"message": "..."}。
- 更高级的响应类(性能优化)
如果对JSON序列化性能有要求,可以安装orjson,然后使用ORJSONResponse替代默认的JSONResponse。
from fastapi.responses import ORJSONResponse
app = FastAPI(default_response_class=ORJSONResponse) # 全局使用
@app.get("/fast-json")
def fast_json():
return {"data": [1,2,3]}
总结:什么时候用什么?
你想要的响应 用什么
返回JSON字典/列表,接受默认状态码200 直接return dict
返回JSON但想把密码等字段藏起来 加response_model=OutputModel
返回JSON需要自定义状态码/头部 return JSONResponse(...)
返回HTML、纯文本、重定向、文件、流 使用对应的HTMLResponse等
整个路由都要返回HTML(简化代码) 装饰器里写response_class=HTMLResponse
需要在文档里标明404等错误格式 使用responses={...}参数