如何在 FastAPI 中将请求重新路由到不同的 URL/端点?

Ani*_*kar 5 python middleware starlette fastapi

我正在尝试在我的 FastAPI 应用程序中编写一个中间件,以便到达与特定格式匹配的端点的请求将被重新路由到不同的 URL,但我无法找到一种方法来做到这一点,因为它request.url是只读的。

我还在寻找一种在重新路由之前更新请求标头的方法。

这些事情在 FastAPI 中可能实现吗?

重定向是迄今为止我能做的最好的事情:

from fastapi import Request
from fastapi.responses import RedirectResponse

@app.middleware("http")
async def redirect_middleware(request: Request, call_next):
    if matches_certain_format(request.url.path):
        new_url = create_target_url(request.url.path)
        return RedirectResponse(url=new_url)
Run Code Online (Sandbox Code Playgroud)

Chr*_*ris 4

要更改request\xe2\x80\x94的URL路径,换句话说,将请求重新路由到不同的端点\xe2\x80\x94,可以在request.scope[\'path\']处理请求之前简单地修改中间件内部的值,如选项中所示3这个答案。如果您的 API 端点包含路径参数(例如\'/users/{user_id}\'),那么您可能需要查看此答案,了解如何从request对象中提取此类路径,然后将其与预定义的列表进行比较routes_to_reroute,如下所示。

\n

至于更新请求标头,或向请求添加新的自定义标头,您可以遵循与此处描述的类似方法,该方法演示了如何修改该request.scope[\'headers\']值。

\n

工作示例

\n

如果您想避免维护要重新路由的路由列表并在中间件内部执行检查,您可以挂载一个子应用程序,该子应用程序将仅包含需要重新路由的路由,并将中间件添加到该子应用程序中-app,类似于这个答案的选项3 。

\n
from fastapi import FastAPI, Request\n\napp = FastAPI()\nroutes_to_reroute = [\'/\']\n\n@app.middleware(\'http\')\nasync def some_middleware(request: Request, call_next):\n    if request.url.path in routes_to_reroute:\n        request.scope[\'path\'] = \'/welcome\'\n        headers = dict(request.scope[\'headers\'])\n        headers[b\'custom-header\'] = b\'my custom header\'\n        request.scope[\'headers\'] = [(k, v) for k, v in headers.items()]\n        \n    return await call_next(request)\n\n@app.get(\'/\')\nasync def main():\n    return \'OK\'\n\n@app.get(\'/welcome\')\nasync def welcome(request: Request):\n    return {\'msg\': \'Welcome!\', \'headers\': request.headers}\n
Run Code Online (Sandbox Code Playgroud)\n