FastAPI 学习二 路径操作
·
一、路径操作
1.2 路径操作装饰器
fastapi支持各种请求方式:
@app.get()
@app.post()
@app.put()
@app.patch()
@app.delete()
@app.options()
@app.head()
@app.trace()
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/get")
def get_test():
return {"method": "get方法"}
@app.post("/post")
def post_test():
return {"method": "post方法"}
@app.put("/put")
def put_test():
return {"method": "put方法"}
@app.delete("/delete")
def delete_test():
return {"method": "delete方法"}
if __name__ == '__main__':
uvicorn.run("路径操作装饰器方法:app", port=8080, debug=True, reload=True)
比如第一个「路径操作函数」:
- 路径:是 /get。
- 操作:是 get。
- 函数:是位于「装饰器」下方的函数(位于 @app.get(“/”) 下方)。

1.2 路径操作装饰器参数:
@app.post(
"/items/{item_id}",
response_model=Item, # 响应类型,其中有过滤功能,报错时返回500,内部错误
status_code=status.HTTP_200_OK, # 用于响应的默认状态码
tags=["AAA"], # 接口标签列表,位置处于接口的上方
summary="this is summary", # 接口总结性内容
description="this is description", # 接口详情内容描述
response_description= "this is response_description", # 响应结果描述
deprecated=False, # 接口是否废弃
)
示例一代码:
# 路径操作装饰器方法的参数.py
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.post("/items", tags=["这是items测试接口"],
summary="items测试 总结性内容", # 接口总结性内容
description="items测试 接口详情描述", # 接口详情内容描述
response_description="这是响应描述,200代表成功",
# deprecated=True, # 接口是否废弃
)
def get_test():
return {"items": "items数据"}
if __name__ == '__main__':
uvicorn.run("路径操作装饰器方法的参数:app", port=8080, debug=True, reload=True)
用浏览器打开 http://127.0.0.1:8080/docs, API文档内容:
示例二代码:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
在路径 / 和 /items/{item_id} 接收 HTTP 请求。
以上两个路径都接受 GET 操作(也称为 HTTP 方法)。
路径 /items/{item_id} 有一个应为 int 的路径参数 item_id。
路径 /items/{item_id} 有一个可选的 str 类型查询参数 q。
用浏览器打开 http://127.0.0.1:8080/items/5?q=somequery
{"item_id": 5, "q": "somequery"}
1.3 路径动态参数
其实上面的示例二就是该动态参数的方式。
简单示例:接口中路径变为动态,根据用户输入的值,进行查询
# 路径参数.py
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/query_user/{user_id}", tags=["获取用户ID"], summary="输入id值,查询用户id")
async def query_user(user_id: int): # 默认是字符串类型,这里转为int
print("user_id的类型", type(user_id))
return {"code": 200, "user_id": user_id}
@app.get("/query_article/{article_id}", tags=["获取文章ID"], summary="输入id值,查询文章id")
async def query_article(article_id: int): # 默认是字符串类型,这里转为int
print("article_id的类型", type(article_id))
return {"code": 200, "article_id": article_id}
if __name__ == '__main__':
uvicorn.run("路径动态参数:app", port=8080, debug=True, reload=True)

1.4 相同路径下优先级匹配
若是我们定义有2个相同路由时,路由有优先级,从上向下匹配。
但是如果配合上动态参数呢,比如我们传入的参数整体的路由正好匹配上了A路由,这时是匹配当前动态参数的B路由呢,还是匹配A路由呢,
下面示例:
# 路径动态参数.py
import uvicorn
from fastapi import FastAPI
app = FastAPI()
# 路由顺序是有影响的
@app.get("/user/me", tags=["获取当前用户名"])
async def read_user_me():
return {"code": 200, "username": "Current user is 【rain】"}
@app.get("/user/{username}", tags=["查询其他用户名"])
async def read_other_user(username: str):
return {"code": 200, "username": f"Other user is 【{username}】"}
if __name__ == '__main__':
uvicorn.run("路径动态参数:app", port=8080, debug=True, reload=True)
若查询中{username}的值=me,那么会优先走上面的路由(/user/me),还是走(/user/{username})?
访问后查看结果:http://127.0.0.1:8080/user/me
结果: 优先走上面的路由(/user/me),这也是因为路由有优先级,从上向下匹配。
我们可以将函数换个顺序再次查看
# 路径动态参数.py
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/user/{username}", tags=["查询其他用户名"])
async def read_other_user(username: str):
return {"code": 200, "username": f"Other user is 【{username}】"}
@app.get("/user/me", tags=["获取当前用户名"])
async def read_user_me():
return {"code": 200, "username": "Current user is 【rain】"}
if __name__ == '__main__':
uvicorn.run("路径动态参数:app", port=8080, debug=True, reload=True)

二、路由分发
2.1 include_router
将路径整合并分发,便于管理
比如,
将带有 /shop/xxx 的路由,都属于购物中心接口。
将带有 /user/xx 的路由,都属于用户中心接口。
这样归属完一类之后,再写路由就在某一类下写,就容易区分,而不是都写在一个页面中,如果有上百上千个,这样做明显是不合理的。
目录结构
|-- apps
|--app01
|--__init__.py
|--urls.py
|--app02
|--__init__.py
|--urls.py
|-- main.py

下面在创建文件夹,表示某一个类的路由内容,这样就比较灵活了
app01.urls.py
from fastapi import APIRouter
user = APIRouter()
@user.post("/login",
summary="这是一个登录页",
description="这是登录页的具体描述", # 接口详情内容描述
response_description="这是登录页响应结果的描述",
)
def login():
return {"code": 200, "user": "登录"}
@user.post("/index",
summary="这是一个首页",
description="这是首页的具体描述", # 接口详情内容描述
response_description="这是首页响应结果的描述",
)
def index():
return {"code": 200, "message": "首页"}
app02.urls.py
from fastapi import APIRouter
shop = APIRouter()
@shop.post("/reg",
summary="这是一个reg页",
description="这个接口不再使用,弃用状态", # 接口详情内容描述
deprecated=True, # 接口是否废弃
)
def login():
return {"code": 404, "user": "reg"}
@shop.post("/buy",
summary="这是一个购买商品的页面",
)
def index():
return {"code": 200, "message": "购买"}
最后创建一个main.py
from fastapi import FastAPI
import uvicorn
from apps.app01.urls import user
from apps.app02.urls import shop
app = FastAPI()
# 将路径整合并分发,便于管理
app.include_router(user, prefix="/user", tags=["用户中心接口"])
app.include_router(shop, prefix="/shop", tags=["购物中心接口"])
if __name__ == '__main__':
uvicorn.run("main:app", port=8080, debug=True, reload=True)
# 接口文档内容:http://127.0.0.1:8080/docs
app.include_router(user, prefix="/user", tags=["用户中心接口"])
第一个参数:路由对象
第二个参数:路由都会加上该前缀
第三个参数:表示属于哪一类,打上标签名称。
文档展示如下:
测试:
更多推荐
所有评论(0)