【问题标题】:How to define multiple API endpoints in FastAPI with different paths but the same path parameter?如何在 FastAPI 中定义多个具有不同路径但相同路径参数的 API 端点?
【发布时间】:2022-11-20 02:09:21
【问题描述】:

我正在开发一个使用 FastAPI 的项目。我的路由器文件如下所示:

# GET API Endpoint 1
@router.get("/project/{project_id}/{employee_id}")
async def method_one(
    project_id: str, organization_id: str, session: AsyncSession = Depends(get_db)
):

    try:
        return await CustomController.method_one(
            session, project_id, employee_id
        )
    except Exception as e:
        return custom_exception_handler(e)

# GET API Endpoint 2
@router.get("/project/details/{project_id}")
async def method_two(
    project_id: str, session: AsyncSession = Depends(get_db)
):

    try:
        return await CustomController.method_two(
            session=session, project_id=project_id
        )
    except Exception as e:
        return custom_exception_handler(e)

# GET API Endpoint 3
@router.get("/project/metadata/{project_id}")
async def method_three(
    project_id: str, session: AsyncSession = Depends(get_db)
):
    try:
        return await CustomController.method_three(
            session=session, project_id=project_id
        )
    except Exception as e:
        return custom_exception_handler(e)
        

这里对工作流的明显期望是:当这些 API 端点中的每一个都被它们所需的路径参数触发时,控制器方法将被执行,如它们的主体中所定义的那样。

但是,由于一些奇怪的原因,当 API 端点 2 和 3 被触发时,它们正在执行端点 1 中的控制器方法,即 CustomController.method_one()

在路由器的方法method_one() 中添加一些print() 语句后,我观察到在调用 API 端点 2 时调用了 method_one(),而它实际上应该在路由器中调用 method_two()。 API 端点 3 的情况也是如此。

我无法理解为什么在触发 API 端点 2 和 3 时执行 method_one() 的方法体。我是不是在配置上遗漏了什么,或者什么——有人可以纠正我吗?谢谢!

【问题讨论】:

    标签: python rest fastapi fastapiusers fastapi-crudrouter


    【解决方案1】:

    在 FastAPI 中,如 this answer 中所述,因为端点是按顺序计算的(请参阅 order matters),它确保您首先在应用程序中定义的端点(在本例中为 /project/{project_id}/...)将被计算第一的。因此,每次调用其他两个端点之一时,即/project/details/.../project/metadata/...,都会触发第一个端点,使用detailsmetadata作为project_id参数。

    解决方案

    因此,您需要确保声明了其他两个端点/project/{project_id}/... 的那个。例如:

    # GET API Endpoint 1
    @router.get("/project/details/{project_id}")
        # ...
    
    # GET API Endpoint 2
    @router.get("/project/metadata/{project_id}")
        # ...
    
    # GET API Endpoint 3
    @router.get("/project/{project_id}/{employee_id}")
        # ...
    

    【讨论】:

      猜你喜欢
      • 2020-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-17
      • 2022-01-25
      • 2023-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多