前言
在 Flask 中,我们一般用蓝图 Blueprint 来处理多个模块的视图,在fastapi 中也有类似的功能通过APIRouter 来管理。
路由管理 APIRouter
如果你正在开发一个应用程序或 Web API,很少会将所有的内容都放在一个文件中。
FastAPI 提供了一个方便的工具,可以在保持所有灵活性的同时构建你的应用程序(如果你学过 Flask,那这将相当于 Flask 的 Blueprints)。
假设你的文件结构如下:
├── app
│ ├── __init__.py
│ ├── main.py
│ └── routers
│ │ ├── __init__.py
│ │ ├── items.py
│ │ └── users.py
app 目录包含了所有内容。并且它有一个空文件 app/__init__.py
,它包含一个 app/main.py
文件。
routers 目录下有 items.py
和 users.py
2个文件。
假设专门用于处理用户逻辑的文件是位于 /app/routers/users.py 的子模块
from fastapi import APIRouter
router = APIRouter()
@router.get("/users/", tags=["users"])
async def read_users():
return [{"username": "Rick"}, {"username": "Morty"}]
@router.get("/users/me", tags=["users"])
async def read_user_me():
return {"username": "fakecurrentuser"}
@router.get("/users/{username}", tags=["users"])
async def read_user(username: str):
return {"username": username}
假设你在位于 app/routers/items.py 的模块中还有专门用于处理应用程序中「项目」的端点。
这和 app/routers/users.py
的结构完全相同。
我们知道此模块中的所有路径操作都有相同的:
- 路径 prefix:路径前缀 /items。
- tags:(仅有一个 items 标签)。
- responses: 定义响应状态码
- dependencies:依赖项。
因此,我们可以将其添加到 APIRouter 中,而不是将其添加到每个路径操作中。
from fastapi import APIRouter, Depends, HTTPException
router = APIRouter(
prefix="/items",
tags=["items"],
responses={404: {"description": "Not found"}},
)
fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}
@router.get("/")
async def read_items():
return fake_items_db
@router.get("/{item_id}")
async def read_item(item_id: str):
if item_id not in fake_items_db:
raise HTTPException(status_code=404, detail="Item not found")
return {"name": fake_items_db[item_id]["name"], "item_id": item_id}
@router.put(
"/{item_id}",
tags=["custom"],
responses={403: {"description": "Operation forbidden"}},
)
async def update_item(item_id: str):
if item_id != "plumbus":
raise HTTPException(
status_code=403, detail="You can only update the item: plumbus"
)
return {"item_id": item_id, "name": "The great Plumbus"}
FastAPI 主体
现在,让我们来看看位于 app/main.py 的模块。在这里你导入并使用 FastAPI 类。
from fastapi import Depends, FastAPI
from .routers import items, users
app = FastAPI()
app.include_router(users.router)
app.include_router(items.router)
@app.get("/")
async def root():
return {"message": "Hello Bigger Applications!"}