Using nginx I am trying to redirect API calls to an external API provider website but after a lot of research and tries I feel I miss something important.
For example, my goal is when I open https://mywebsite/api/somedata
, then a remote API provider is called https://api-somewebsite.com/somedata
.
My basic try was:
location /api/ {
proxy_pass https://api-somewebsite.com/;
}
I added a log format to try to get more informations:
log_format upstreamlog '[$time_local] $remote_addr - $remote_user - $server_name $host to: $upstream_addr: $request $status upstream_response_time $upstream_response_time msec $msec request_time $request_time';
Then used it to log the calls:
location /api/ {
proxy_pass https://api-somewebsite.com/;
access_log /var/log/nginx/upstream.log upstreamlog;
}
And it seems that the /api/ part is not well removed:
[21/Sep/2022:11:23:17 -0400] 88.163.105.196 - - - mywebsite.com mywebsite.com to: xxx.xx.xx.xx:xxx, xxx.xx.xx.xx:xxx: GET /api/somedata HTTP/1.1 502 upstream_response_time 0.005, 0.008 msec 1663773797.354 request_time 0.012
So basically it seems to call https://api-somewebsite.com/àpi/somedata
which does not exist and thus return 502 error.
I have read that with the trailing /
the /api/
part should be well removed automatically. But it does not work. So I tried to rewrite it by myself:
location /api/ {
proxy_pass https://api-somewebsite.com/;
access_log /var/log/nginx/upstream.log upstreamlog;
rewrite ^/api/(.*) /$1 break;
}
Still no luck.
I ended up trying some stuff found on the web but that I do not fully understand... like adding proxy_redirect instruction:
location /api/ {
proxy_pass https://api-somewebsite.com/;
access_log /var/log/nginx/upstream.log upstreamlog;
rewrite ^/api/(.*) /$1 break;
proxy_redirect https://api-somewebsite.com/ /api/;
}
Well, I feel that I lack some basic stuff to make it work, but I cannot find what. Any insights would be greatly appreciated.
====== EDIT 1 ======
According to Stephen Dunne answer, i tried to add an upstream for the server. Here is my edited code:
upstream magiceden {
server api-mainnet.magiceden.dev:443 max_fails=0;
zone magiceden-api 64k;
keepalive 60;
}
server {
server_name genoverse.me www.genoverse.me;
location / {
root /home/hcomere/genoverse.me;
index index.html;
}
location /magiceden_api/ {
proxy_pass https://magiceden/;
access_log /var/log/nginx/access_magiceden.log upstreamlog;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/genoverse.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/genoverse.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
I still have error 502 - Bad Gateway - when visiting https://www.genoverse.me/magiceden_api/ where i should get an error 400 - Not found - from the api provider https://api-mainnet.magiceden.dev/
====== EDIT 2 ======
Oh well, i discovered that browsers have a redirect cache, this explain why sometimes things did not work where they should work. Once i cleared the redirect cache after each config modification, things were way more smooth and understandable !...
CodePudding user response:
I think the issue here is that you are using a Uri and not an upstream.
I have read that with the trailing / the /api/ part should be well removed automatically.
This is correct.
Try adding an upstream for the server.
upstream somesite {
server api-somewebsite.com:443 max_fails=0;
zone somesite-api 64k;
keepalive 60;
}
And then use the upstream in your location block (keeping the trailing slash)
location /api/ {
proxy_pass https://somesite/;
access_log /var/log/nginx/upstream.log upstreamlog;
}
Now when you browse to the /api location you should be redirected as expected.