时间:2025-07-18 14:48
人气:
作者:admin
在 APISIX 中,proxy-rewrite 插件的 regex_uri 功能是实现复杂路由重写的核心工具。下面我将全面总结各种转发场景的使用方法和技巧。
"regex_uri": ["匹配正则", "替换模板"]
$1, $2 等引用捕获组"regex_uri": ["^/api/v1/(.*)", "/backend/$1"]
请求转换:
/api/v1/users → /backend/users/api/v1/products/123 → /backend/products/123"regex_uri": ["^/user/([^/]+)/profile/(.*)", "/profile/$1/$2"]
请求转换:
/user/john/profile/settings → /profile/john/settings/user/mary/profile/preferences → /profile/mary/preferences"regex_uri": ["^/v1/(.*)", "/v2/$1"]
请求转换:
/v1/orders → /v2/orders/v1/inventory/items → /v2/inventory/items"regex_uri": ["^/product/(\\d+)/detail", "/items/$1"]
请求转换:
/product/123/detail → /items/123/product/456/detail → /items/456"regex_uri": ["^/(user|product)/(create|delete)/([a-z]+)", "/action/$2/$1/$3"]
请求转换:
/user/create/account → /action/create/user/account/product/delete/item → /action/delete/product/item"regex_uri": ["^/search/(.*)", "/query/$1"]
请求转换:
/search/books?category=sci-fi → /query/books?category=sci-fi/search/movies?year=2023 → /query/movies?year=2023"regex_uri": ["^/([a-z]{2})/([a-z]+)/?$", "/$2/$1"]
请求转换:
/en/home → /home/en/es/about → /about/es"regex_uri": ["^/(?:api|service)/v(\\d+)/(.*)", "/v$1/$2"]
请求转换:
/api/v2/users → /v2/users/service/v3/products → /v3/products"plugins": {
"proxy-rewrite": {
"regex_uri": ["^/user/(.*)", "/$1"],
"vars": [
["http_x_api_version", "==", "v2"]
]
}
}
仅当请求头 X-API-Version: v2 时生效
"plugins": [
{
"proxy-rewrite": {
"regex_uri": ["^/api/", "/"]
}
},
{
"proxy-rewrite": {
"regex_uri": ["^/v1/", "/v2/"]
}
}
]
分阶段重写:
/api/v1/users → /v1/users/v1/users → /v2/users"plugins": {
"proxy-rewrite": {
"uri": "/new-base",
"regex_uri": ["^/old/(.*)", "/$1"]
}
}
组合效果:
/old/path → /new-base/path/other → /new-base/other非捕获组优化:使用 (?:) 代替 () 避免不必要的捕获
"regex_uri": ["^/(?:api|service)/v(\\d+)/(.*)", "/v$1/$2"]
避免贪婪匹配:使用 .*? 代替 .* 防止过度匹配
"regex_uri": ["^/category/(.*?)/(detail)", "/$2/$1"]
精确锚定:使用 ^ 和 $ 限定匹配范围
"regex_uri": ["^/exact/path$", "/new/exact"]
curl "http://127.0.0.1:9080/apisix/admin/plugin_metadata/proxy-rewrite" \
-H "X-API-KEY: your-admin-key" -X PUT -d '
{
"regex_uri_debug": true
}'
在 error.log 中查看匹配详情:
2023/10/15 14:30:22 [debug] regex_uri match: pattern=^/api/(.*), uri=/api/v1/users, matches=1
2023/10/15 14:30:22 [debug] regex_uri replace: /api/v1/users -> /v1/users
local rewrite = require("apisix.plugins.proxy-rewrite")
local ctx = {var = {uri = "/old/path"}}
rewrite.rewrite({regex_uri = {"^/old/(.*)", "/new/$1"}}, ctx)
ngx.say(ctx.var.uri) -- 输出: /new/path
解决方案:
regex_uri_debug: true正确写法:
"regex_uri": ["^/search\\?q=(.+)", "/query/$1"]
"regex_uri": ["", "$0"] -- 保留完整原始路径
"regex_uri": ["(?i)^/api/(.*)", "/$1"] -- 忽略大小写
路径标准化:在网关层统一路径格式
"regex_uri": ["^/[A-Z]+/(.*)", "/${lower($1)}"]
版本控制:无缝升级 API 版本
"regex_uri": ["^/v1/(.*)", "/v2/$1"]
多租户支持:
"regex_uri": ["^/([a-z0-9]+)/api/(.*)", "/tenants/$1/$2"]
A/B 测试路由:
"regex_uri": ["^/service/(.*)", "/service-v2/$1"],
"vars": [["http_x_test_group", "==", "B"]]
协议升级重定向:
"plugins": {
"proxy-rewrite": {
"regex_uri": ["^(.*)", "https://new-domain.com$1"],
"scheme": "https"
}
}
| 方法 | 复杂度 | 适用场景 | 性能影响 |
|---|---|---|---|
| regex_uri | 中-高 | 复杂路径转换 | 中(PCRE 编译) |
| uri 直接替换 | 低 | 简单前缀修改 | 低 |
| 多插件组合 | 高 | 分阶段处理 | 中-高 |
| Nginx 原生 rewrite | 中 | 深度定制 | 最低 |
建议:简单场景使用
uri直接替换,复杂场景使用regex_uri
1. 静态改写,不需要正则
"proxy-rewrite": {
"uri": "/auth/realms/xx/protocol/openid-connect/token/introspect"
}
2. 表达url一级路径的文件名,扩展名是.txt,例如:http://www.sina.com/1.txt
"proxy-rewrite": {
"regex_uri": [
"^/([^/]+\\.txt)$",
"/auth/$1"
]
}
3. 按前缀进行替换
"proxy-rewrite": {
"regex_uri": [
"^/user-xx(/.*)",
"$1"
]
}
4. 以某个前缀开头的,在转发时,在前缀前面添加固定字符,下面添加了apim-es到apim-admin的前面
"proxy-rewrite": {
"regex_uri": [
"\"^/apim-admin/(.*)\"",
"/apim-es/$1"
]
}
作者:仓储大叔,张占岭,
荣誉:微软MVP
QQ:853066980
支付宝扫一扫,为大叔打赏!
