Fornisce più endpoint proxy nella posizione in Nginx


13

Ho un paio di endpoint API che desidero servire da un'unica posizione /apicon sottotracciati che vanno a endpoint diversi. In particolare, desidero che webdis sia disponibile su /apie un'API proprietaria disponibile su /api/mypath.

Non sono preoccupato per gli scontri con l'API webdis perché sto usando percorsi secondari che difficilmente si scontreranno con i nomi dei comandi redis e hanno anche il pieno controllo sulla progettazione dell'API per evitare gli scontri.

Ecco il file di configurazione dal mio server di test su cui ho hackerato:

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

Come posso modificare la mia soluzione alternativa in modo che eventuali richieste /api/mypath/*vadano all'endpoint alla porta 3936 e tutto il resto alla porta 7379?


Cosa intendi con tried this to no avail? Che cosa è successo quando hai attivato quella direttiva sulla posizione? Connesione finita? Posizione non corrispondente?
Masegaloeh,

Ah, grazie per la richiesta, sta dando un errore non trovato, su ulteriori indagini sembra che l'errore provenga dalla mia API, quindi funziona! : D Ma la regola di riscrittura ovviamente non è perché devo aggiungere v1 all'URL ( localhost / api / mypath / v1 / about ) ... :(
hamstar

Risposte:


23

Non è necessario riscrivere per questo.

server {
  ...

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

Secondo la documentazione di nginx

Una posizione può essere definita da una stringa di prefisso o da un'espressione regolare. Le espressioni regolari vengono specificate con il ~*modificatore precedente (per la corrispondenza senza distinzione tra maiuscole e minuscole) o il ~modificatore (per la corrispondenza con distinzione tra maiuscole e minuscole). Per trovare la posizione corrispondente a una determinata richiesta, nginx controlla innanzitutto le posizioni definite usando le stringhe del prefisso (posizioni prefisso). Tra questi, viene selezionata e ricordata la posizione con il prefisso corrispondente più lungo. Quindi vengono controllate le espressioni regolari, nell'ordine del loro aspetto nel file di configurazione. La ricerca di espressioni regolari termina alla prima corrispondenza e viene utilizzata la configurazione corrispondente. Se non viene trovata alcuna corrispondenza con un'espressione regolare, viene utilizzata la configurazione della posizione del prefisso ricordata in precedenza.

Se la posizione del prefisso corrispondente più lunga ha il ^~modificatore, le espressioni regolari non vengono controllate.

Pertanto, qualsiasi richiesta che inizia con /api/mypath/sarà sempre servita dal secondo blocco poiché è la posizione del prefisso corrispondente più lunga .

Qualsiasi richiesta che inizia con /api/non immediatamente seguito da mypath/sarà sempre servita dal primo blocco, poiché il secondo blocco non corrisponde, rendendo quindi il primo blocco la posizione del prefisso corrispondente più lunga .


2
Se si guardano le modificatori posizione ( =, ~*, ~e ^~) può sembrare contro-intuitivo che ^~esclude le espressioni regolari (in quanto ~indica una corrispondenza espressione regolare) ... però, se vi ricordate, ^all'interno di una classe di caratteri espressione regolare (ad esempio [^a-z]) nega che classe (tale che l'esempio significa (qualsiasi carattere tranne quelli di az); allo stesso modo, ^~annulla qualsiasi potenziale blocco di posizione delle espressioni regolari.
Doktor J

6

OK ho capito, pensavo che l'errore "non trovato" provenisse da nginx, ma in realtà proveniva dalla mia API. Questa è la mia soluzione se qualcuno è interessato:

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/;
  }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.