Search code examples
djangonginxroutesuritastypie

How to mediate Django-Tastypie URI with Nginx routing


Specifically, I think I need Nginx to not consume (capture?) a piece of the URI I'm using to route a location. But I don't know if such a thing is possible.


Let me back up. I'm transitioning my app's setup. Before, I had an Nginx config file with a single location block matching everything:

server {
    listen   80;
    server_name ec2-54-234-175-21.compute-1.amazonaws.com;

    location / {
        ...
        proxy_pass http://localhost:8000/;
    }

With this setup, up until now, I've just been running a Django app. After Nginx routes the user to the only endpoint, Django consumes the whole URI. What this means is that internally, Django chops off /api/ and then just has 1.0, which it also needs.

Now, I'm going to use Nginx to proxy for multiple servers, each hosting an app. Because of the aforementioned internal routing, the Django app needs to receive (at least) a URI of /1.0, while the other (on Flask) needs to get /api/2.0. However, in order for the Nginx location directives to make any sense, I have to differentiate the two applications. What I've worked out is that I'll just have the following two location directives:

server {
    listen   80;
    server_name ec2-54-234-175-21.compute-1.amazonaws.com;

    location /api/[1.0] {
        ...
        proxy_pass http://localhost:8000/;
    }

    location / {
        ...
        proxy_pass http://localhost:8080/;
    }

However, note the [1.0] in brackets. If that is there, what I've realized is that in order to actually access the intended resource, I have to enter a URI of /api/1.0/1.0. So, somehow I need a non-consuming location in my nginx conf. If I knew how to express this in simpler terms, I would. Is what I want possible?


Solution

  • About a week after asking this question, a coworker pointed out the answer I wanted, and it's very simple. The key is in the malleability that Nginx gives you with its routing. Because I wanted to access a resource that was at /api/1.0, but still needed to differentiate the two apps in my config, I do the following:

    server {

    listen   80;
    server_name ec2-54-234-175-21.compute-1.amazonaws.com;
    
    location /api/1.0 {
        ...
        proxy_pass http://localhost:8000/api/1.0;
    }
    location /api/2.0 {
        ...
        proxy_pass http://localhost:8080/api/2.0;
    }
    

    This effectively makes the URL "non-consuming", as I wrote above, because I use the desired resource URL to route with, and then duplicate it in referencing the actual location within the specific app.

    Maybe this will help someone else.