当你创建一个 FastAPI 路径操作 时,你可以正常返回以下任意一种数据:dictlist,Pydantic 模型,数据库模型等等。

FastAPI 默认会使用 jsonable_encoder 将这些类型的返回值转换成 JSON 格式,
默认情况下会以content-type: application/json 格式返回

在有些情况下,我们需要在路径操作中直接返回Response对象,这样我们能有更多的操作灵活性,比如自定义头headers 信息、自定义Cookie信息等

默认返回 json 格式

返回一个基本数据类型 dict,list,str 会以 json 格式返回


from fastapi import FastAPI  
import uvicorn  
  
app = FastAPI()  
  
  
@app.get('/demo')  
def demo():  
    item = {  
        "name": "yoyo",  
        "email": "123@qq.com"  
    }  
    return item

get 请求访问 http://127.0.0.1:8000/demo

HTTP/1.1 200 OK
date: Tue, 18 Jul 2023 10:50:41 GMT
server: uvicorn
content-length: 36
content-type: application/json

{"name":"yoyo","email":"123@qq.com"}

JSONResponse 自定义返回

可以使用 from starlette.responses import JSONResponse 定制返回内容,包含响应状态码,响应headers 和 响应body

JSONResponse 继承自 Response 类,部分源码如下:

class JSONResponse(Response):  
    media_type = "application/json"  
  
    def __init__(  
        self,  
        content: typing.Any,  
        status_code: int = 200,  
        headers: typing.Optional[typing.Dict[str, str]] = None,  
        media_type: typing.Optional[str] = None,  
        background: typing.Optional[BackgroundTask] = None,  
    ) -> None:  
        super().__init__(content, status_code, headers, media_type, background)

JSONResponse可传参数:

  • content: 响应body内容,str 或者 bytes.
  • status_code: 响应状态码,int类型,默认200.
  • headers: 响应头部,dict类型.
  • media_type:media type. 例如"text/html".
  • background:后台任务

自定义 JSONResponse 响应, status_code 可以自定义状态码.
FastAPI 会自动包含 Content-Length,以及Content-Type,charset等头信息。

from fastapi import FastAPI, status  
from fastapi.responses import JSONResponse  
import uvicorn  
  
app = FastAPI()  
  
  
@app.get('/demo')  
def demo():  
    item = {  
        "name": "yoyo",  
        "email": "123@qq.com"  
    }  
    return JSONResponse(  
        content=item, status_code=status.HTTP_201_CREATED  
    )

get 请求访问http://127.0.0.1:8000/demo

HTTP/1.1 201 Created
date: Tue, 18 Jul 2023 10:59:53 GMT
server: uvicorn
content-length: 36
content-type: application/json

{"name":"yoyo","email":"123@qq.com"}

于是可以看到响应状态码变成了 201 。

自定义返回 headers 和 media_type

响应头部添加 headers 内容和设置 media_type 响应 body 媒体类型


from starlette.responses import JSONResponse  
  
  
@app.get('/resp/demo')  
async def resp_demo():  
    return JSONResponse(  
        'hello world',  
        status_code=201,  
        headers={"x-token": "aa11233"},  
        media_type="text/html"  
    )

FastAPI学习-14. JSONResponse 返回JSON内容_自定义