1. 介绍

FastAPI框架自带了对请求参数的验证,包括在路径中的参数、请求的参数以及Body中的参数,使用Path提取和验证路径参数;使用Query提取和验证?请求中的参数,使用Body将参数让客户端由body(默认application/json方式)传入。示例如下:

#示例python代码
from fastapi import FastAPI, Path, Query, Body
app = FastAPI()

# 通过get方式在URL路径中接收请求参数
@app.get("/items/{item_id}")
async def read_root1(item_id: int = Path(..., gt=0)):
    return {"item_id": item_id}

# 虽然是通过post方式提交请求,但item_id仍然是在URL中通过?item_id进行请求
@app.post("/items")
async def read_root2(item_id: int = Query(..., ge=1)):
    return {"item_id": item_id}

# post方式提交请求,但item_id仍然是在URL中通过?item_id进行请求
@app.post("/items")
async def read_root2(
	item_id: int = Body(..., ge=1, embed=True),
	item_name: str = Body(None, max_length=25)):
    return {"item_id": item_id, "item_name": item_name}

第三种情况要注意,有时你明明使用的app.post方式,但是服务端接受不到数据,就是因为参数没有带上Body()方法,直接使用int=1这种默认值,这种处理虽然设置了app.post,请求的时候仍然是在URL中通过?item_id进行请求。此时使用Body再加上embed=True表示将参数名放入body实体中做为健值对来请求。另外可以不使用Body,而使用BaseModel,如下:

from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel

#定义一个model,继承BaseModel
class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

app = FastAPI()

#请求是只需要写Item即可。
@app.post("/items/")
async def create_item(item: Item):
    return item

继承自BaseModel的接收体只能通过POST来发送。如上面的例子中,参数有使用max_length这种设置,这是 Path, Query, Body的参数验证。这三种实现方式和使用参数方式都差不多,大同小异。列一下验证规则:

2. Query验证规则

def Query( 
    default: Any,
    *,
    alias: str = None,    #请求参数别名,使用了alias就必须使用alias的参数名传参。
    title: str = None,   #没有发现哪里有用
    description: str = None,  #没有发现哪里有用
    gt: float = None, #大于某值
    ge: float = None, #大于等于某值
    lt: float = None, #小于某值
    le: float = None, #小于等于某值
    min_length: int = None,  #最小长度
    max_length: int = None,  #最大长度
    regex: str = None,  #正则规则
    deprecated: bool = None,   # True表示将要是废弃的接口
    **extra: Any,
)

Body的话还有一个media_type属性,默认str值为application/json,其它的就都一样的。参数没有通过验证框架就会抛出412状态码并带有detail描述的json字符串。