Proxy / Rewrite your API Endpoint into Domain Segment with Nginx

I wanted to make an API available on the same domain as a single page app built with Vue.js, which means that I had to rewrite a part of the domain to use another port on the same host, but you can also use an entirely different machine or have a load balancer in between.

This post is part of the Making Of: photographerexcuses.com series.

I picked nginx for a server for some PHP productions and this because it simply has the best configs and it tends to perform a bit better if you don't have a lot of RAM to throw at your server.

If you want to see the full site config, just scroll to the bottom (SSL settings redacted).

The most important part to rewrite a portion of your site or even specific URLs to another port, in this case the Go API, this portion is the most important:

location /api/excuse {
    rewrite          ^/api/item(/.*)$ $1 break;
    proxy_pass       http://127.0.0.1:4000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_redirect   off;
}

This will make every request that nginx gets be proxied to http://127.0.0.1:4000, not rewritten. It will appear as if it's at http://photographerexcuses.com/api/item, but actually it's passing it on to the other app. Otherwise these requests would simply show a 404 page, because the single page app basically only has the index.html file.

Also $1 on the same line means that anything after that will be passed along, like /api/item/141 will go to http://127.0.0.1:4000/141, which we needed to get a specific ID to be queried.

server {

    listen   80; ## listen for ipv4
    listen   :80[::]:80 default ipv6only=on; ## listen for ipv6

    server_name  photographerexcuses.com;

    access_log  /var/log/nginx/photographerexcuses.access.log;
    error_log  /var/log/nginx/photographerexcuses.error.log;

    root /var/www/photographerexcuses.com/;

    location / {
        root   /var/www/photographerexcuses.com;
            try_files $uri $uri/ /index.html;
        index  index.php index.html;
    }

    # rewrite `http://www` to `http://`
    if ($host ~* ^www\.(.*))
    {
        set $host_without_www $1;
        rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
    }

    location /api/excuse {
        rewrite ^/api/excuse(/.*)$ $1 break;
        proxy_pass http://127.0.0.1:4000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_redirect    off;
    }

    add_header X-Clacks-Overhead "GNU Terry Pratchett";
}
Tagged with: #API #Nginx #proxy

Thank you for reading! If you have any comments, additions or questions, please tweet or toot them at me!