我有几个 API 端点,我想从 的单个位置提供服务,/api
子路径指向不同的端点。具体来说,我希望 webdis 在 可用/api
,专有 API 在 可用/api/mypath
。
我并不担心与 webdis API 发生冲突,因为我使用的子路径不太可能与 redis 命令名称发生冲突,并且可以完全控制 API 的设计以避免冲突。
这是我一直在攻击的测试服务器的配置文件:
server {
listen 80;
server_name localhost;
server_name 192.168.3.90;
server_name 127.0.0.1;
location / {
root /home/me/src/phoenix/ui;
index index.html;
}
# temporary hardcoded workaround
location = /api/mypath/about {
proxy_pass http://localhost:3936/v1/about;
}
location /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://localhost:7379/;
}
# tried this but it gives "not found" error
#location ^~ /api/mypath/ {
# rewrite ^/api/mypath/(.*)$ /$1 break;
# proxy_pass http://localhost:3936/v1/;
#}
#
#location ^~ /api {
# rewrite ^/api/(.*)$ /$1 break;
# proxy_pass http://localhost:7379/;
#}
}
我怎样才能改变我的解决方法,以便任何请求都/api/mypath/*
将发送到端口 3936 的端点,而其他所有请求都将发送到端口 7379?
答案1
您不需要为此重写。
server {
...
location ^~ /api/ {
proxy_pass http://localhost:7379/;
}
location ^~ /api/mypath/ {
proxy_pass http://localhost:3936/v1/;
}
}
根据nginx 文档
位置既可以由前缀字符串定义,也可以由正则表达式定义。正则表达式使用前面的
~*
修饰符(用于不区分大小写的匹配)或~
修饰符(用于区分大小写的匹配)指定。要查找与给定请求匹配的位置,nginx 首先检查使用前缀字符串定义的位置(前缀位置)。在其中,选择并记住具有最长匹配前缀的位置。然后按照正则表达式在配置文件中出现的顺序检查正则表达式。正则表达式的搜索在第一次匹配时终止,并使用相应的配置。如果未找到与正则表达式匹配的项,则使用先前记住的前缀位置的配置。如果最长匹配的前缀位置有
^~
修饰符,则不检查正则表达式。
因此,任何以开头的请求/api/mypath/
将始终由第二个块处理,因为这是最长匹配前缀位置。
/api/
任何以 开头且不紧跟 的请求mypath/
将始终由第一个块处理,因为第二个块不匹配,因此第一个块是最长匹配前缀位置。
答案2
好的,我明白了,我以为“未找到”错误来自 nginx,但实际上它来自我的 API。如果有人感兴趣的话,这是我的解决方案:
server {
listen 80;
server_name localhost;
server_name 192.168.3.90;
server_name 127.0.0.1;
location / {
root /home/me/src/phoenix/ui;
index index.html;
}
# automatically go to v1 of the (grape) API
location ^~ /api/mypath/ {
rewrite ^/api/mypath/(.*)$ /v1/$1 break;
proxy_pass http://localhost:3936/;
}
location ^~ /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://localhost:7379/;
}
}