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;