如何通过Mangum在AWS Lambda上正确路由FastAPI以避免404错误?
问题描述
我有一个基于FastAPI+Mangum开发的AWS Lambda函数,通过AWS API Gateway绑定自定义域名后,访问以下路径始终返回{"detail":"Not Found"}错误:
https://api.domain.com/api/v1/usershttps://api.domain.com/api/v1/users/1
添加捕获所有请求的路由后,返回的路径信息显示path_name为api/v1/users和api/v1/users/1,但现有FastAPI路由(/、/users、/users/{user_id})无法匹配这些请求。
当前代码如下:
from fastapi import FastAPI, Request from mangum import Mangum app = FastAPI() # /api/v1/users/ @app.get("/") def read_root(): return {"Hello": "World"} @app.get("/users") def read_root(): return {"Hello": "Users"} @app.get("/users/{user_id}") def user_item(user_id: int, q: str = None): return {"user_id": user_id, "q": q} # My catch all code #@app.api_route("/{path_name:path}", methods=["GET"]) #async def catch_all(request: Request, path_name: str): # return {"request_method": request.method, "path_name": path_name} handler = Mangum(app, lifespan="off")
解决方案
问题核心是API Gateway转发给Lambda的请求包含/api/v1前缀,但FastAPI的路由未适配该前缀,导致匹配失败。以下是三种可行解决方式:
1. 给FastAPI设置root_path
初始化FastAPI时指定root_path参数,直接匹配API Gateway的路径前缀:
# 初始化时添加root_path,对应API Gateway的路径前缀/api/v1 app = FastAPI(root_path="/api/v1")
此方式无需修改现有路由,FastAPI会自动将/api/v1作为根路径,原/users路由将匹配/api/v1/users请求。
2. 调整API Gateway路径映射
若不想修改代码,可在API Gateway控制台调整自定义域名的路径映射:
- 找到目标自定义域名,进入路径映射编辑页面
- 将源路径设为
/api/v1,目标路径设为/(或/*,根据API类型调整) - 保存后重新部署API,API Gateway会自动去掉
/api/v1前缀再转发请求,原有FastAPI路由即可正常匹配。
3. 给路由统一添加前缀
使用FastAPI的APIRouter给所有路由添加前缀:
from fastapi import FastAPI, APIRouter router = APIRouter(prefix="/api/v1") @router.get("/") def read_root(): return {"Hello": "World"} @router.get("/users") def read_users(): return {"Hello": "Users"} @router.get("/users/{user_id}") def user_item(user_id: int, q: str = None): return {"user_id": user_id, "q": q} app = FastAPI() app.include_router(router)
此方式需调整路由结构,将相关路由统一放到带前缀的APIRouter中。
验证方式
修改完成后,取消注释捕获路由并重新部署Lambda,再次访问https://api.domain.com/api/v1/users,若返回{"Hello": "Users"}而非捕获路由的内容,说明路由匹配成功。
内容的提问来源于stack exchange,提问作者Johnny John Boy
相关产品推荐
相关产品推荐

