Nginxの場所で複数のプロキシエンドポイントを提供する


13

/apiサブパスが異なるエンドポイントに移動する単一の場所からサービスを提供したいAPIエンドポイントがいくつかあります。具体的には、webdisをで/api、独自のAPIをで入手できるようにし/api/mypathます。

redisコマンド名と衝突する可能性が低いサブパスを使用しているため、webdis APIとの衝突については心配していません。また、衝突を避けるために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に送信されるように回避策を変更するにはどうすればよいですか?


どういう意味tried this to no availですか?その場所ディレクティブを有効にするとどうなりましたか?接続タイムアウト?場所が一致しませんか?
マセガロー14

ああ、プロンプトに感謝します。エラーが見つかりませんでした。さらに調査してみると、エラーがAPIから発生しているようです。:Dしかし、v1をURL(localhost / api / mypath / v1 / about)に追加する必要があるため、書き換えルールは明らかにそうではありません... :(
hamstar

回答:


23

これを書き換える必要はありません。

server {
  ...

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

nginxのドキュメントによると

場所は、プレフィックス文字列または正規表現で定義できます。正規表現は、前の~*修飾子(大文字と小文字を区別しないマッチングの場合)または~修飾子(大文字と小文字を区別するマッチングの場合)で指定されます。特定のリクエストに一致する場所を見つけるために、nginxは最初にプレフィックス文字列(プレフィックスの場所)を使用して定義された場所をチェックします。その中で、最長の一致するプレフィックスを持つ場所が選択され、記憶されます。次に、構成ファイルでの出現順に正規表現がチェックされます。正規表現の検索は最初の一致で終了し、対応する構成が使用されます。正規表現との一致が見つからない場合は、以前に記憶されたプレフィックスロケーションの設定が使用されます。

最長一致プレフィックス位置に^~修飾子がある場合、正規表現はチェックされません。

したがって/api/mypath/、2番目のブロックは最も長い一致するプレフィックスの場所であるため、最初のリクエストは常に2番目のブロックによって処理されます。

2番目のブロックは一致しないため、/api/直後に続かないで始まるリクエストmypath/は常に最初のブロックによって処理されます。したがって、最初のブロックが最も一致するプレフィックスの場所になります。


2
あなたは、位置修飾子を見れば(=~*~、及び^~)それは直観に反するように見えるかもしれない^~除外正規表現(以降は、~正規表現の一致を示す)...しかし、あなたは思い出す場合は、^正規表現の文字クラスの内側(例えば[^a-z]ネゲートことクラス(例では(a〜z 以外の任意の文字)意味します。同様に、^~潜在的な正規表現の場所ブロックを否定します。
Doktor J

6

OKでそれがわかりました。「見つかりません」というエラーは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/;
  }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.