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


1 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;