Vercel路由中间件支持Python:FastAPI/Flask/Django通用

Vercel路由中间件支持Python,可在FastAPI/Flask/Django前统一处理请求。
Vercel 的路由中间件正式支持 Python,开发者可在请求到达主应用之前插入一层独立的 ASGI 或 WSGI 应用,实现请求重写、重定向、请求头注入或直接返回响应。启用方式是在 vercel.toml 的 proxy.entrypoint 中指定入口,依赖隔离在 pyproject.toml 的 vercel.proxy 组中。官方 vercel-proxy 包提供 Proxy 类,用装饰器按路径注册处理函数,支持路径参数与通配匹配;ContinueResponse 可在保留原请求的前提下改写请求头再放行,未匹配请求原样透传。该中间件适合路径迁移、API 版本头注入、灰度分流等轻量前置逻辑,不适合数据库查询等重量级操作。
Vercel路由中间件支持Python:FastAPI/Flask/Django通用
Vercel 的路由中间件(Routing Middleware)正式支持 Python 了。这意味着使用 FastAPI、Flask、Django 等 Python 框架的开发者,现在可以在请求到达主应用之前插入一层独立的处理逻辑,对请求进行重写、重定向或直接返回响应。

中间件运行在应用之前
与传统的框架内中间件不同,Vercel 的这套路由中间件是一个独立运行的 ASGI 或 WSGI 应用。它在请求进入主应用之前执行,因此适合处理跨应用的通用逻辑,比如旧路径迁移、API 版本头注入、灰度分流等。
这种"前置拦截"的定位带来一个实际好处:中间件代码与业务代码解耦,主应用不需要为了路由层面的规则而修改框架配置。对于多框架并存的团队,同一套中间件思路可以复用到不同技术栈。
ASGI 与 WSGI 是 Python Web 生态中两个层次的服务器-应用接口标准。WSGI(Web Server Gateway Interface,PEP 3333)是同步传统标准,Django、Flask 默认基于它构建;ASGI(Asynchronous Server Gateway Interface)是异步演进版,支持 async/await、WebSocket 和长连接,FastAPI、Starlette 采用它。两者本质都是约定应用对象如何被服务器调用:WSGI 应用是可调用对象 app(environ, start_response),ASGI 应用是 async def app(scope, receive, send)。Vercel 路由中间件作为独立 ASGI/WSGI 应用运行,意味着它不依赖主应用框架的请求对象,只要符合接口约定,就能在 FastAPI、Flask、Django 等不同框架前统一挂载,这也是它能跨技术栈复用的技术前提。
配置方式:vercel.toml 指向入口
启用方式是在 vercel.toml 中通过 proxy 字段指定入口文件:
[proxy]
entrypoint = "proxy:proxy"
这里的 proxy:proxy 遵循模块名加对象名的引用形式,指向你编写的中间件实例。配置本身很轻量,真正的逻辑都写在 Python 文件里。
依赖管理上,中间件拥有独立的依赖组。官方要求把中间件导入的包加入 pyproject.toml 的 vercel.proxy 依赖组,例如可通过 uv add --group vercel.proxy vercel-proxy 安装官方工具包。这种隔离设计避免了中间件依赖与主应用依赖相互污染——中间件只需要它真正用到的那几个包,冷启动和构建体积都能受益。
依赖组(dependency group) 是 PEP 735 引入的 pyproject.toml 标准特性,允许在 [dependency-groups] 下把依赖划分为开发、测试、部署等若干命名组,由 uv 等工具按组安装。它与 optional-dependencies 类似但语义更清晰:后者面向包使用者按需安装额外功能,依赖组则面向项目自身的不同运行环境。把中间件依赖放进 vercel.proxy 组,构建时只安装该组,主应用依赖不会被拉入中间件的构建产物,从而减小冷启动体积、避免版本冲突。
用 Proxy 类按路径分发请求
官方提供的 vercel-proxy 包封装了一个 Proxy 应用,用装饰器风格按路径注册处理函数。下面的例子把旧博客路径永久重定向到新路径:
from urllib.parse import quote
from vercel.proxy import ContinueResponse, Proxy, RedirectResponse, Request, Response
proxy = Proxy()
@proxy.route("/old-blog/{slug}")
def old_blog(request: Request) -> Response:
slug = quote(request.path_params["slug"])
return RedirectResponse(f"/blog/{slug}", status_code=308)
路径参数通过 request.path_params 读取,返回值使用框架提供的响应类型。308 状态码表示永久重定向且保留请求方法,适合做站点结构迁移。
改写请求头后放行
中间件更常见的用法是"改一下再放行"。ContinueResponse 允许你在保留原请求的前提下附加或覆盖请求头,然后交给主应用继续处理:
@proxy.route("/api/{path:path}")
def api(request: Request) -> Response:
return ContinueResponse(request_headers={"x-api-version": "2"})
这段代码为所有 /api/ 开头的请求注入 x-api-version: 2 头。注意 {path:path} 这种通配写法可以匹配多级路径,适合 API 前缀类的批量规则。对于未匹配任何路由的请求,中间件会原样放行到主应用,不会造成阻塞。
308 与 301 的区别 值得单独说明:两者都是永久重定向,浏览器和搜索引擎会缓存并更新索引。差异在于 301 允许客户端把 POST 改为 GET,而 308 明确规定必须保留原请求方法和请求体。对 API 与表单提交场景,若用 301 可能导致方法被改写、请求体丢失;308 能确保迁移后语义不变。代价是 308 相对较新,极老的客户端可能不识别,因此纯 GET 的页面迁移用 301 也无妨,涉及非 GET 方法时优先 308。
适合哪些场景
从能力边界看,这套中间件擅长三类任务:路径级别的重定向与重写、请求头的统一注入、以及基于路径的分流决策。它不适合承担重量级业务逻辑——独立运行意味着它拿不到主应用的运行时上下文,也不应承担数据库查询这类耗时操作。
对已经在 Vercel 上部署 Python 应用的团队来说,这次更新填补了"应用层之前"的控制空白。过去这类需求往往要在框架层面写中间件,或者依赖平台的重写规则;现在可以用熟悉的 Python 代码统一表达,并且跨框架复用。
需要查阅完整参数和响应类型的话,官方提供了 Routing Middleware Python 参考文档。
相关推荐

Gemini 4 Argon实测:AI自主造桌游、建寺庙、训机器人
Gemini 4 Argon 实测汇总:AI 自主用 Blender 搭建书桌赛道与寺庙、编写光线追踪引擎、训练人形机器人连进7球,并附 API 定价与开发者接入方式。

魔法八边形硬币:为何仅9%的人能预测它的翻转?
魔法八边形硬币仅9%的人能正确预测其翻转方向。本文解析其空间旋转机制、常见认知误区,并介绍基于相关性理论的新假说,探讨人类空间推理的局限。

Sam Altman:AI正迈入科学发现时代,数学突破将复制到生物与能源
Sam Altman 表示 AI 正进入科学发现时代,数学领域的突破方法将复制到生物学、材料科学和能源领域,帮助研发新药与新能源。他认为这种影响不会让人直接感知,而是融入社会日常运转。