如何使用 Mangum 在 AWS Lambda 上正确路由 FastAPI 以避免“未找到”错误?

问题描述 投票:0回答:1

我有一个 AWS Lambda 函数,但似乎无法使用 AWS API Gateway 连接到自定义域。当我卷曲时,我总是遇到

{"detail":"Not Found"}
错误:

https://api.domain.com/api/v1/users
https://api.domain.com/api/v1/users/1

我添加了一个 catch all 以返回方法和请求,代码如下所示,但我不知道如何将其与返回的 url 匹配:

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")

当取消注释时,会正确返回路径名:

{"request_method":"GET","path_name":"api/v1/users"}
{"request_method":"GET","path_name":"api/v1/users/1"}

我完全陷入困境,但我认为这与前缀或默认根有关。

aws-lambda aws-api-gateway fastapi mangum
1个回答
0
投票

所以需要做三件事来解决这个问题:

  1. 首先,我需要指定一个
    api_gateway_base_path='/api/v1/users'
    ,以便 Mangum 知道
    api.domain.com/api/v1/users
    的 AWS 根路径在哪里。这没有给我任何文档,但确实允许我访问
    /users/
    /users/whatever
  2. 然后我需要指定
    root_path="/api/v1/users"
    ,然后我才能访问
    api.domain.com/api/v1/users/docs
  3. 不幸的是我仍然有一个问题
    api.domain.com/api/v1/users
    仍然是“未找到”。为了解决这个问题,我必须添加一条额外的路线
    @app.get('', include_in_schema=False)
    来捕获没有尾部正斜杠的路线。我为 include_in_schema 添加了 False,因此自动文档系统不会为同一路线生成相同的文档。

最终代码如下所示:

from datetime import datetime

from fastapi import FastAPI, Request
from mangum import Mangum
from pydantic import BaseModel

app = FastAPI(
    root_path="/api/v1/users"
)  

@app.get('', include_in_schema=False)
@app.get("/")
def read_root(request: Request):
    return {"Hello": "Users"}



# @app.api_route("/{path_name:path}", methods=["GET"])
# async def catch_all(request: Request, path_name: str):
#     print(request.scope)
#     return {
#         "request_method": request.method,
#         "root_path": request.scope['root_path'],
#         "raw_path": request.scope['raw_path'],
#         "path": request.scope['path'],
#         "path_name": path_name
        
#     }

handler = Mangum(
    app, 
    lifespan="off", 
    api_gateway_base_path='/api/v1/users'
)
© www.soinside.com 2019 - 2024. All rights reserved.