现在有一个实际的问题,我们在完成某一个项目的时候,如果说用户非要从接口传递一些非法参数或者某些人想要搞破坏,传递恶意的参数。如果参数直接与数据库相关,恶意传入一些参数会直接影响到数据库的正常运行,所以我们该怎么处理这些非法参数呢?写个函数验证?但是接口那么多,无穷尽也。但是fastapi提供了一些优雅的解决方式!
额外的校验
下面是一段代码:  
1 2 3 4 5 6 7 8 9 10
   | from typing import Optional
  from fastapi import FastAPI, Query
  app = FastAPI()
 
  @app.get("/router/") async def read_items(q: Optional[str] = None):     pass
   | 
 
需求是限制参数q的长度
Query
官方提供了一个库叫做Query,这个库可以非常简单的做校验,如下:
1 2 3 4 5 6 7 8 9 10
   | from typing import Optional
  from fastapi import FastAPI, Query
  app = FastAPI()
 
  @app.get("/router/") async def read_items(q: Optional[str] = Query(None, max_length=50)):     pass
   | 
 
功能
我们直接从源码上看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | def Query(       default: Any,     *,     alias: Optional[str] = None,     title: Optional[str] = None,     description: Optional[str] = None,     gt: Optional[float] = None,     ge: Optional[float] = None,     lt: Optional[float] = None,     le: Optional[float] = None,     min_length: Optional[int] = None,     max_length: Optional[int] = None,     regex: Optional[str] = None,     example: Any = Undefined,     examples: Optional[Dict[str, Any]] = None,     deprecated: Optional[bool] = None,     include_in_schema: bool = True,     **extra: Any, ) -> Any:
   | 
 
其实根据翻译就能够得出这些参数大概是什么意思,如gt、ge、lt、le分别是大于、大于等于、小于、小于等于。但是其中有一个功能却十分强大,即regex。
是的,参数校验可以使用正则表达式,在官方给定的案例中,我们可以看到正则表达式的使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | from typing import Optional
  from fastapi import FastAPI, Query
  app = FastAPI()
 
  @app.get("/items/") async def read_items(     q: Optional[str] = Query(None, min_length=3, max_length=50, regex="^fixedquery$") ):     results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}     if q:         results.update({"q": q})     return results
   | 
 
这个指定的正则表达式通过以下规则检查接收到的参数值:
- ^:以该符号之后的字符开头,符号之前没有字符。
 
- fixedquery: 值精确地等于 fixedquery。
 
- $: 到此结束,在 fixedquery 之后没有更多字符。
 
当然,别名参数alias也是十分有用的,如果你不想让调用函数的人通过参数揣测你的接口含义,你可以通过给参数命别名的方式来混淆别人对函数的判断,从而保证函数的安全。当然,别名也可以使得参数更加规范,或许?