前面我们介绍的 FastApi
响应体都是使用不同的结构体进行的,有 str
、list
、json
等,但是这在前后台分离的场景下是不友好的。为了方便前端处理,我们一般会使用统一的数据结构作为响应。
针对常用的响应码,我们可以封装符合自己业务需求的结构体。比如自定义响应码,自定义 message
等。
我们可以使用 Python
的字典类型对统一结构体进行组装,然后根据不同的响应码封装不同的方法去实现统一响应。
我们还可以将公共的内容固定下来,作为 base struct
使用。
mycode.py
from fastapi import status
from fastapi.responses import JSONResponse
from typing import Union
# 定义响应统一结构体
def resp_200(*, data: Union[list, dict, str]):
'''
200系列的响应结构体
*:代表调用方法时必须传参数
Union:代表传入的参数可以是多种类型
'''
return JSONResponse(
status_code=status.HTTP_200_OK,
content={
'code': 0,
'message': "Success",
'data': data,
}
)
def resp_400(*, data: str, message='Bad Request!'):
'''
400系列的响应结构体
*:代表调用方法时必须传参数
'''
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={
'code': 1,
'message': message,
'data': data,
}
)
鉴于文章篇幅长度,我们这里只用
200
和400
响应体进行演示。
我们在 FastApi
的 App
中将 mycode
导入,即可直接使用。
response_fengzhuang.py
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse,JSONResponse
import uvicorn
import time
from resp_code import mycode
app = FastAPI()
# 为app增加接口处理耗时的响应头信息
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
# X- 作为前缀代表专有自定义请求头
response.headers["X-Process-Time"] = str(process_time)
return response
@app.get('/{ck}')
async def index(request: Request,ck:int):
#print(request.headers)
if ck < 10:
return mycode.resp_200(data='关注:Python全栈开发')
else:
return mycode.resp_400(data=f'ck的值不对:{ck}')
if __name__ == '__main__':
uvicorn.run(app='response_fengzhuang:app',
host='localhost', port=1331, reload=True)
文件结构
如上,当我们访问/9
的时候,后端返回 200
系列结构体,访问/10
的时候,后端返回 400
系列结构体。
如上,
200
和400
响应体结构都是一致,前端根据code
即可处理请求。