Exibição de vários pontos de extremidade do proxy em localização no Nginx

7

Eu tenho alguns pontos de extremidade de API que desejo veicular em um único local de /api , com subpaths indo para diferentes endpoints. Especificamente, quero que o webdis esteja disponível em /api e uma API proprietária disponível em /api/mypath .

Não estou preocupado com confrontos com a API do webdis porque estou usando subcaminhos que provavelmente não colidirão com nomes de comando redis e também têm controle total sobre o design da API para evitar conflitos.

Aqui está o arquivo de configuração do meu servidor de teste que eu tenho invadido:

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/;
  #}
}

Como posso alterar a minha solução alternativa para que qualquer solicitação para /api/mypath/* vá para o ponto de extremidade na porta 3936 e tudo mais para a porta 7379?

    
por hamstar 08.12.2014 / 23:44

2 respostas

14

Você não precisa reescrever isso.

server {
  ...

  location ^~ /api/ {
    proxy_pass http://localhost:7379/;
  }
  location ^~ /api/mypath/ {
    proxy_pass http://localhost:3936/v1/;
  }
}

De acordo com a documentação do nginx

A location can either be defined by a prefix string, or by a regular expression. Regular expressions are specified with the preceding ~* modifier (for case-insensitive matching), or the ~ modifier (for case-sensitive matching). To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.

If the longest matching prefix location has the ^~ modifier then regular expressions are not checked.

Portanto, qualquer solicitação que comece com /api/mypath/ será sempre veiculada pelo segundo bloco, pois esse é o local do prefixo correspondência mais longa .

Qualquer solicitação que comece com /api/ não imediatamente seguida por mypath/ sempre será atendida pelo primeiro bloco, já que o segundo bloco não corresponde, portanto, tornando o primeiro bloco a correspondência mais longa localização do prefixo.

    
por 09.12.2014 / 08:15
6

OK, descobri que o erro "not found" estava vindo do nginx, mas na verdade vinha da minha API. Esta é a minha solução se alguém estiver interessado:

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/;
  }
}
    
por 09.12.2014 / 00:19