Reputation: 79
I am working with my nginx server and I have no idea how to add /api prefix to the existing url.
I have two endpoints /api/deepzoom and /api/detection exposed by Flask. I don't want to change the code in frontend that call /deepzoom and /detection yet.
How can I rewrite/redirect the url path to /api/deepzoom when called from frontend with /deepzoom
My current snippet in nginx.conf:
upstream platform {
server platform:5001;
}
upstream models {
server models:4999;
}
upstream deepzoom {
server deepzoom:5999;
}
server {
listen 80 ;
server_name myhost.mydomain.com;
client_max_body_size 0;
client_body_buffer_size 1m;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
send_timeout 10m;
proxy_buffer_size 512k;
proxy_buffers 4 1024k;
proxy_busy_buffers_size 1024k;
proxy_redirect off;
location ^~ /api/detection/ {
include uwsgi_params;
proxy_pass http://models;
}
location ^~ /api/deepzoom/ {
include uwsgi_params;
proxy_pass http://deepzoom;
}
location / {
include uwsgi_params;
proxy_pass http://platform;
}
}
I have tried to add the lines in server block:
rewrite ^ /detection/ http://$server_name/api/detection/$1 permanent;
rewrite ^ /deepzoom/ http://$server_name/api/deepzoom/$1 permanent;
but it doesn't work with 404 Not Found error.
Anyone can help me to figure it out and how to satisfy the requirement. Thanks!
Upvotes: 5
Views: 29435
Reputation: 1678
I found this question while trying to add a prefix to the path for a React app I'm running in front of nginx. I wanted all requests to the app to have the prefix /mypref
because my app files were in a subdirectory called /mypref
. If a url already started with /mypref
, I wanted to "forward" the remaining part of the url to index.html so it could be handled by react-router. The following nginx configuration did the trick for me:
# redirect requests not matching /mypref so that they start with /mypref/...
location / {
absolute_redirect off;
return 301 /mypref$request_uri;
}
# This config allows access to nested routes directly.
# Example: Without this, if you accessed https://myapp.com/mypref/my-requests directly, it
# would fail. You would need to access https://myapp.com/mypref/ first, and then navigate to
# the nested route.
# With this config in place, you can go to the nested route and anything after /mypref/ automatically gets passed to
# the index file so that it can be handled by react-router
location /mypref {
absolute_redirect off;
if (!-e $request_filename) {
rewrite ^(.*)$ /mypref/ break;
}
index index.html index.htm Default.htm;
}
I used relative redirects here since my app was in front of a gateway and I didn't want users leaving the gateway.
Upvotes: 0
Reputation: 49702
The rewrite...permanent
statements in your question are badly formed and do not perform the function you require.
permanent
causes a redirection with a 301 response^
and /
characters$1
To internally rewrite the URI before passing it upstream, you can use rewrite...last
. See this document for details.
For example:
rewrite ^(/(detection|deepzoom)(/.*)?)$ /api$1 last;
location ^~ /api/detection { ... }
location ^~ /api/deepzoom { ... }
Note, if your endpoint is /api/deepzoom
, then you do not want a trailing /
on your location
value.
You can achieve a similar behaviour using the proxy_pass
directive. See this document for details.
For example:
location ^~ /deepzoom {
include uwsgi_params;
proxy_pass http://deepzoom/api/deepzoom;
}
Take care that both the location
and proxy_pass
values have a trailing /
or neither have a trailing /
.
Upvotes: 10