How to Configure Nginx Location Blocks for Multiple API Proxy Endpoints with Subpath Routing


10 views

When setting up reverse proxies in Nginx, we often need to route different API endpoints under a common base path while preserving their individual subpaths. The specific requirement here involves:

  • Routing /api/* to Webdis (port 7379)
  • Routing /api/mypath/* to a custom API (port 3936)

The key is understanding Nginx's location matching priority:

location = /exact/match   # Highest priority
location ^~ /prefix       # Prefix-based priority
location ~ /regex         # Regex match (case sensitive)
location ~* /regex        # Regex match (case insensitive)
location /prefix          # General prefix match

Here's the complete solution that meets our requirements:

server {
  listen 80;
  server_name localhost 192.168.3.90 127.0.0.1;

  location / {
    root /home/me/src/phoenix/ui;
    index index.html;
  }

  # Handle mypath routes first (higher priority)
  location ^~ /api/mypath/ {
    rewrite ^/api/mypath/(.*)$ /v1/$1 break;
    proxy_pass http://localhost:3936;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }

  # Catch-all for other /api routes
  location /api/ {
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://localhost:7379;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}

1. Order Matters: The more specific /api/mypath/ location must come before the general /api/ location.

2. Rewrite Handling: The break flag in rewrite rules prevents further rewriting.

3. Proxy Headers: Essential headers maintain request context between hops.

Verify with these test cases:

# Should hit Webdis
curl http://localhost/api/SET/foo/bar

# Should hit custom API
curl http://localhost/api/mypath/about

# Should serve static files
curl http://localhost/index.html

For production environments, consider adding:

# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

# Timeout settings
proxy_connect_timeout 5s;
proxy_read_timeout 30s;

# Load balancing
upstream webdis {
  server 127.0.0.1:7379;
  server backup.example.com:7379 backup;
}

When building API gateways with Nginx, we often need to route different subpaths under a common base URL to separate backend services. Here's a robust solution for handling /api and /api/mypath routing.

server {
  listen 80;
  server_name localhost 192.168.3.90 127.0.0.1;

  location / {
    root /home/me/src/phoenix/ui;
    index index.html;
  }

  # Specific path routing first
  location ^~ /api/mypath/ {
    rewrite ^/api/mypath/(.*)$ /v1/$1 break;
    proxy_pass http://localhost:3936/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }

  # Catch-all for other /api requests
  location /api/ {
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://localhost:7379/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}
  • The ^~ modifier ensures Nginx gives priority to the more specific path
  • Proper rewrite rules maintain clean backend URLs
  • Proxy headers ensure proper request forwarding
  • Order of location blocks matters - specific paths must come first

Verify with curl commands:

# Test webdis endpoint
curl http://localhost/api/SET/foo/bar

# Test proprietary API
curl http://localhost/api/mypath/about

Consider adding these directives to each proxy_pass block for better error handling:

proxy_intercept_errors on;
error_page 502 503 504 /50x.html;

For production environments, add these optimizations:

proxy_http_version 1.1;
proxy_set_header Connection "";
keepalive_timeout 60;
keepalive_requests 1000;