在使用FastAPI进行API开发时,常常需要对请求参数进行验证和清洗,以确保接口的安全性和稳定性。本文将介绍如何在FastAPI中实现请求数据的验证和清洗,并给出代码示例。
1. 安装依赖
在使用FastAPI进行开发时,常常需要引入一些第三方依赖来辅助开发。在本文中,我们需要安装以下依赖:
- pydantic:用于数据验证和清洗
- typing-extensions:用于在pydantic中定义数据类
在命令行中执行以下命令:
pip install pydantic typing-extensions
2. 定义请求数据类
在FastAPI中,我们可以使用pydantic来定义一个数据类,用于对请求参数进行验证和清洗。一个数据类通常包含多个属性,每个属性表示一个请求参数。我们可以在属性上使用pydantic提供的验证装饰器来指定该属性的验证规则,例如最大长度、最小值等。
下面是一个示例数据类的定义:
from typing import Optional
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
is_offer: Optional[bool] = None
2.1 数据类的属性
在定义数据类时,每个属性都表示一个请求参数。属性的类型可以是基本类型,如str、int、float等,也可以是其他数据类,甚至可以是一个列表或字典。
在上述示例中,Item数据类有三个属性:name、price和is_offer,分别对应一个商品的名称、价格和是否有优惠。其中,name属性的类型为str,表示商品名称;price属性的类型为float,表示商品价格;is_offer属性的类型为Optional[bool],表示是否有优惠,可以为空。
2.2 验证装饰器
在数据类的属性上,我们可以使用pydantic提供的验证装饰器来指定该属性的验证规则。以下是一些常用的验证装饰器:
- max_length:最大长度
- min_length:最小长度
- gt:大于
- ge:大于等于
- lt:小于
- le:小于等于
- regex:正则表达式匹配
- email:邮箱地址格式
- url:URL格式
例如,以下代码使用max_length验证装饰器限制了name属性的最大长度为50个字符:
from pydantic import BaseModel, validator
class Item(BaseModel):
name: str
price: float
is_offer: bool = False
@validator('name')
def name_must_be_shorter_than_50_characters(cls, v):
if len(v) > 50:
raise ValueError('name must be shorter than 50 characters')
return v
3. 声明请求数据
在FastAPI的路由中,我们可以声明一个参数来接收请求数据,并指定该参数的类型为定义的数据类。此时,FastAPI会自动根据参数的类型来验证和清洗请求数据,并将清洗后的数据注入到该参数中。
例如,以下代码是一个路由函数,接收一个类型为Item的参数:
@app.post('/items/')
async def create_item(item: Item):
return item
在请求该接口时,我们可以将请求数据作为JSON格式的消息体发送。FastAPI会自动解析JSON消息体并根据数据类自动验证和清洗请求数据,然后将清洗后的数据注入到item参数中。
4. 使用FastAPI自带的Body参数解析器
除了使用pydantic定义数据类外,FastAPI还提供了自带的Body参数解析器,用于自动解析请求消息体并验证和清洗请求数据。我们可以在路由函数的参数列表中使用这个参数解析器,来代替手动定义数据类的方式。
例如,以下代码使用FastAPI自带的Body参数解析器来解析请求消息体,并验证和清洗请求数据:
@app.post('/items/')
async def create_item(item: dict = Body(...)):
return item
在上述代码中,我们声明了一个名为item的参数,并将其类型指定为dict。由于我们使用了Body(...),所以FastAPI会自动解析请求消息体,并验证和清洗请求数据。如果请求数据无法通过验证,FastAPI会抛出异常。
总结
本文介绍了在FastAPI中实现请求数据验证和清洗的方法。我们可以使用pydantic定义数据类,也可以使用FastAPI自带的Body参数解析器来解析请求消息体。通过验证和清洗请求数据,我们可以确保接口的安全性和稳定性,为后续的数据处理和业务逻辑提供良好的基础。