FastAPI 提供动态路由的能力,在其官网上将其称之为路径参数,允许你使用与Python格式化字符串相同的语法来声明路径"参数"或"变量"。
一个API接口需要返回用户的基本信息,比较传统的URL设计可能是下面的这样
/userinfo?uid=3
API接口的path 是 /userinfo ,url里的query部分是uid=3, 通过变化uid这个查询参数以获取不同用户的基本信息。
Restful 风格的API接口设计则是下面的样子
/userinfo/3
用户的uid 成为了接口url path里的一部分,想要获取uid 为4的用户的基本信息,请求的path为/userinfo/4, 在使用路由模块定义请求path与处理函数之间的映射关系时,你不可能根据uid穷举所有用户的path,这就要求路由模块必允许你定义一个可动态变化的url结构,这便是动态路由。
from fastapi import FastAPI
app = FastAPI()
@app.get('/userinfo/{uid}')
def user_info(uid):
return {'msg': f"recv uid :{uid} type is {str(type(uid))}"}
启动服务后在浏览器里访问 http://127.0.0.1:8000/userinfo/5 ,得到的响应结果如下
{"msg":"recv uid :5 type is <class 'str'>"}
表示path的字符串 '/userinfo/{uid}' 采用了python格式化字符串时的语法,被{} 括起来的部分是允许发生变化的地方。
在上一小节的例子中,函数user_info的参数uid 实际传入的实参是字符串类型,这与uid通常为int类型的实践状态是不相符的,FastAPI允许你通过类型标注对路径参数进行转化
@app.get('/userinfo/{uid}')
def user_info(uid: int):
return {'msg': f"recv uid :{uid} type is {str(type(uid))}"}
为参数uid 增加类型标注,将其标注为int类型,FastAPI将根据这个标注对uid进行类型转换,接口返回的内容变为
{"msg":"recv uid :5 type is <class 'int'>"}
uid被自动转为int类型,如此便不需要你自己再进行任何的转换,这正是FastAPI可以提高你工作效率的原因。
一旦你对路径参数进行了类型标注,如果在实际请求中传入了错误的参数,FastAPI可以帮你校验并返回错误,以第3小节的例子为基础,在浏览器里访问 http://127.0.0.1:8000/userinfo/string, string 不能转化为int类型数据,这是一次错误的请求,FastAPI返回的结果是
{
"detail": [
{
"loc": [
"path",
"uid"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
现在新增一个API接口
@app.get('/userinfo/all')
def user_info_all():
return {'msg': "all user info"}
@app.get('/userinfo/{uid}')
def user_info(uid: int):
return {'msg': f"recv uid :{uid} type is {str(type(uid))}"}
路径 /userinfo/all 和 '/userinfo/{uid}' 是相似的,如果请求/userinfo/all 被user_info函数 处理了,all不能转为int类型数据,服务会报错。但实践中,这样写不会发生错误,,当请求/userinfo/all 到来时,user_info_all 和 user_info 都可以用来处理请求,但user_info_all定义在前,因此优先使用user_info_all 对请求进行处理。
QQ交流群: 211426309