FastAPI教程-路由获取参数 作者:马育民 • 2026-08-05 17:37 • 阅读:10004 ## 二、路径参数(路径变量) URL路径里的变量,用`{变量名}`,函数参数接收。FastAPI自动做类型校验。 ```python # 路径参数 @app.get("/items/{item_id}") def read_item(item_id: int): # 自动转int,非数字直接返回422校验错误 return {"item_id": item_id} ``` ### 路径参数优先级规则 **静态路径 > 变量路径,顺序从上到下匹配,先定义先匹配** ```python @app.get("/items/me") # 静态路径,优先匹配 def read_me(): return {"me": True} @app.get("/items/{item_id}") def read_item(item_id:int): return {"id":item_id} ``` ⚠️ 如果把`/{item_id}`写在`/me`前面,访问`/items/me`会把`me`赋值给`item_id`,报int转换异常。 ### 路径参数带枚举限制 ```python from enum import Enum class ModelName(str, Enum): alexnet = "alexnet" resnet = "resnet" @app.get("/models/{model_name}") def get_model(model_name: ModelName): return {"model": model_name} ``` ### 路径包含路径(`path`类型,匹配`/`) `/files/{file_path:path}`可以匹配带斜杠的路径,例如`/files/a/b/c.txt` ```python @app.get("/files/{file_path:path}") def read_file(file_path: str): return {"file_path": file_path} ``` ## 三、查询参数(Query参数,url?key=value) 不在路径中,在`?`后面,函数普通参数就是查询参数。 ```python @app.get("/items/") def read_items(skip: int = 0, limit: int | None = None): return {"skip": skip, "limit": limit} ``` - 带默认值:`skip:int=0`,不传使用默认 - `limit: int | None = None`:可选参数,可以不传 ### Query高级校验 ```python from fastapi import Query @app.get("/products") def qry( page: int = Query(1, ge=1, description="页码>=1"), keyword: str | None = Query(None, min_length=2, max_length=20) ): return locals() ``` ## 四、路由元信息(装饰器参数) ```python @app.get( "/items/{item_id}", summary="获取单个商品", description="根据id获取商品详情", tags=["商品管理"], # openapi文档分组 response_description="返回商品json", deprecated=False, # 是否标记接口废弃 status_code=200, # 默认响应状态码 ) def get_item(item_id:int): return {"id":item_id} ``` ## 五、APIRouter 模块化路由(大型项目必用) 把路由拆分到不同文件,实现接口模块化,统一加前缀、tags。 **items.py** ```python from fastapi import APIRouter router = APIRouter( prefix="/items", # 该组所有路由自动拼接前缀 tags=["商品模块"] ) @router.get("/") def list_items(): return {"data":"商品列表"} @router.get("/{item_id}") def get_one(item_id:int): return {"id":item_id} ``` **main.py** ```python from fastapi import FastAPI from items import router as item_router app = FastAPI() # 注册子路由 app.include_router(item_router) ``` ### APIRouter 参数说明 - `prefix`:统一路径前缀,不要末尾写`/` - `tags`:分组标签 - `dependencies`:该路由组全部接口共用依赖 - `responses`:统一预设错误响应 > 还可以嵌套路由:`include_router`可以多次嵌套。 ## 六、路由的依赖 dependencies ### 单接口依赖 ```python from fastapi import Depends def get_token(): return "abc123" @app.get("/secret", dependencies=[Depends(get_token)]) def secret(): return {"ok":True} ``` ### APIRouter全局依赖,组内全部接口生效 ```python router = APIRouter( prefix="/admin", dependencies=[Depends(check_admin)] ) ``` ### app全局依赖(所有接口) ```python app = FastAPI(dependencies=[Depends(global_auth)]) ``` ## 七、路由响应配置 1. `response_model`:过滤输出字段,Pydantic模型 2. `status_code`:返回状态码 3. `responses`:额外文档的错误码示例 ```python from pydantic import BaseModel class ItemOut(BaseModel): id:int name:str @app.get("/item/{id}", response_model=ItemOut, status_code=200, responses={404:{"description":"找不到"}}) def get_item(id:int): return {"id":id,"name":"xxx","secret":"不会返回"} ``` ## 八、路由匹配原理 1. 请求进来,starlette遍历注册的路由列表,从上往下匹配; 2. 优先完全静态匹配,再匹配路径参数; 3. 匹配成功执行对应函数; 4. 函数参数解析来源:路径参数、query、body、header、cookie、依赖; 5. pydantic校验参数,校验失败返回422; 6. 返回值自动json序列化。 > ⚠️重要:**路由定义顺序很关键,静态路由写在变量路由前面,否则会被变量路由拦截**。 ## 九、特殊路由 ### 1. 重定向 RedirectResponse ```python from fastapi.responses import RedirectResponse @app.get("/go") def go(): return RedirectResponse("/docs") ``` ### 2. 文件响应 FileResponse ```python from fastapi.responses import FileResponse @app.get("/download") def download(): return FileResponse("test.txt") ``` ### 3. 挂载子应用(mount) 把另外一个starlette/fastapi应用挂载到某个路径下,不是路由,是完整子应用。 ```python from fastapi import FastAPI sub_app = FastAPI() @sub_app.get("/hello") def h():return {"hi":"sub"} app = FastAPI() app.mount("/sub", sub_app) # 访问 /sub/hello ``` > `mount` 和 `include_router`区别: > - `include_router`:只是把路由规则合并到主app,共享文档; > - `mount`:挂载完整独立应用,openapi文档不会合并。 ## 十、常用路由调试工具 访问自动文档: - SwaggerUI:`/docs` - ReDoc:`/redoc` ## 完整项目目录示例(模块化) ``` main.py routers/ __init__.py user.py goods.py ``` main.py ```python from fastapi import FastAPI from routers.user import router as user_router from routers.goods import router as goods_router app = FastAPI(title="路由演示") app.include_router(user_router) app.include_router(goods_router) ``` routers/user.py ```python from fastapi import APIRouter router = APIRouter(prefix="/user", tags=["用户"]) @router.get("/list") def user_list(): return {"users":[]} ``` ## 常见坑总结 1. 路由顺序错误,静态接口被路径参数接口拦截; 2. `prefix="/items/"`末尾多斜杠,导致拼接双斜杠;推荐`prefix="/items"`; 3. 路径参数类型写错,请求直接422; 4. `mount`和`include_router`混淆,子应用看不到文档; 5. POST接口,把参数写为普通函数参数,误当成query参数(body参数需要pydantic模型)。 如果你需要,我可以给你一份可直接运行完整示例代码,或者讲路由内部源码解析。 原文出处:/show_1GW3ooojxtbd.html