Nginx中RESTful API路径重写核心是内部重写(如rewrite+last)或反向代理(proxy_pass+截断),前者映射到PHP入口,后者透传至后端服务并修正响应头,需精准正则、避免贪婪匹配、合理使用last/break及try_files兜底。

RESTful API 路径重写在 Nginx 中核心是把形如 /api/v1/users/123 这类语义化路径,映射到后端能识别的入口(比如 PHP 的 index.php 或反向代理的目标服务),同时保持 URL 干净、符合 REST 规范。配置关键在于区分「内部重写」和「外部重定向」,多数 REST 场景用的是前者。
用 rewrite 实现内部路径映射(推荐)
这是最常用的方式:客户端看到的是 /api/v1/posts,Nginx 内部把它转成 /index.php?m=api&c=posts 或直接代理到后端服务,浏览器地址栏不变。
- 确保
ngx_http_rewrite_module已启用(默认编译包含) - 正则要精准匹配层级,避免误伤静态资源
- 使用
last标志让 Nginx 重新匹配 location,适合转发给 PHP 或统一入口
示例(适配常见 PHP REST 框架):
location /api/ {
# 捕获 v1/v2 + 控制器 + 方法 + ID
if ($uri ~ ^/api/v(\d+)/([^/]+)/([^/]+)/?$) {
set $version $1;
set $controller $2;
set $action $3;
rewrite ^/api/v\d+/[^/]+/[^/]+/?$ /index.php?v=$version&c=$controller&a=$action last;
}
if ($uri ~ ^/api/v(\d+)/([^/]+)/?$) {
set $version $1;
set $controller $2;
rewrite ^/api/v\d+/[^/]+/?$ /index.php?v=$version&c=$controller last;
}
# 兜底:/api/ → 主页或文档
try_files $uri $uri/ /index.php?$args;
}用 proxy_pass 做反向代理(无路径改写)
如果你后端是 PostgREST、Node.js 或 Go 写的独立 API 服务,通常不需要重写路径,只需把请求透传过去,并修正响应头中的路径信息。
- 用
proxy_pass把/api/下所有请求代理到http://localhost:3000/ - 加
proxy_hide_header Content-Location防止后端返回的绝对路径暴露内部端口 - 用
add_header Content-Location重写响应头,保持对外路径一致
示例(对接 PostgREST):
location /api/ {
proxy_pass http://127.0.0.1:3000/;
proxy_hide_header Content-Location;
add_header Content-Location /api/$upstream_http_content_location;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}用 try_files 处理单页 API 文档或 fallback
很多 REST API 提供 Swagger 或 Redoc 页面,部署在 /api/docs/,但前端是 SPA 结构,需要 Nginx 支持 history 模式。
-
try_files $uri $uri/ /api/docs/index.html;表示:先找真实文件,再找目录,最后回退到入口页 - 注意
root或alias设置要与路径匹配,alias更适合子路径映射
示例(托管 Swagger UI):
location /api/docs/ {
alias /var/www/swagger-ui/;
index index.html;
try_files $uri $uri/ /api/docs/index.html;
}避免踩坑的细节
RESTful 路径重写容易出错的地方不在语法,而在逻辑边界和优先级。
-
if在 location 外不推荐嵌套多层,Nginx 官方建议用rewrite+location替代 - 正则中
^/api/v1/([^/]+)/([^/]+)/?$比.*更安全,防止贪婪匹配破坏结构 - 如果用了
last,后续 rewrite 不会执行;用break则终止当前块内所有 rewrite,但不重新匹配 location - 调试时开启
error_log /var/log/nginx/rewrite.log notice;,配合rewrite_log on;查看重写过程


















