У меня есть несколько конечных точек API, которые я хочу обслуживать из одного местоположения /api
с подпути, ведущей к разным конечным точкам. В частности, я хочу, чтобы webdis был доступен по адресу /api
и проприетарный API, доступный по адресу /api/mypath
.
Меня не беспокоят конфликты с API webdis, потому что я использую подпути, которые вряд ли будут конфликтовать с именами команд 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?
Для этого не нужно переписывать.
server {
...
location ^~ /api/ {
proxy_pass http://localhost:7379/;
}
location ^~ /api/mypath/ {
proxy_pass http://localhost:3936/v1/;
}
}
В соответствии с документация nginx
Местоположение может быть определено строкой префикса или регулярным выражением. Регулярные выражения указываются с предыдущим
~*
модификатор (для сопоставления без учета регистра) или~
модификатор (для сопоставления с учетом регистра). Чтобы найти местоположение, соответствующее заданному запросу, nginx сначала проверяет местоположения, определенные с помощью строк префикса (местоположения префиксов). Среди них выбирается и запоминается место с самым длинным совпадающим префиксом. Затем проверяются регулярные выражения в порядке их появления в файле конфигурации. Поиск регулярных выражений завершается при первом совпадении, и используется соответствующая конфигурация. Если совпадения с регулярным выражением не найдено, используется ранее запомненная конфигурация расположения префикса.Если у самого длинного совпадающего префикса есть
^~
модификатор, то регулярные выражения не проверяются.
Поэтому любой запрос, который начинается с /api/mypath/
всегда будет обслуживаться вторым блоком, так как это самое длинное совпадение расположение префикса.
Любой запрос, который начинается с /api/
не сразу следует mypath/
всегда будет обслуживаться первым блоком, так как второй блок не совпадает, поэтому первый блок самое длинное совпадение расположение префикса.
Хорошо, разобрался, я думал, что ошибка «не найдено» исходит от 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/;
}
}