How to deploy static website connecting to Django RESTful API?

自作多情 提交于 2019-12-10 18:23:28

问题


First of all, google or SO search didn't help me: lots of tips regarding django's staticfiles, which I believe are not relevant here.

I have inherited a project consisting of:

  • Django backend in form of API returning JSON responses only;
  • standard Swampdragon deployment pushing realtime updates to frontend; very little configuration has been done here;
  • Frontend webapp built on Backbone and marionette.js, compiled and minified by Grunt.

My problem is: the frontend needs to know addresses for swampdragon and django servers; right now those values are hardcoded, so there is for example a Backbone model with lines like:

url: function() {
    return App.BACKEND_URL+'settings/map';
}

Why hardcoded: backend can be served on any port or have a subdomain to itself; frontend is static and normally would be simply thrown into /var/www (for Apache) or would use some very simple nginx config. Both will be served from the same place, but there is no guarantee the port numbers or subdomains would match.

Idea number 1: try to guess what BACKEND_URL is from javascript, by taking window.location.host and appending standard port. That's hackish and error prone.

Idea number 2: move frontend to Django and make it ask for swampdragon credentials (they would be sent in the context of home view). Problem with that is, the frontend files are compiled by grunt. So where Django would kindly expect something like:

<script src="{% static 'scripts/vendor/modernizr.js' %}"></script>

I actually have

<script src="scripts/vendor/a8bcb0b6.modernizr.js"></script>

Where 'a8bcb0b6' is grunt's hash/version number and will be regenerated during next minification/build. Do I need to add additional logic to get rid of such stuff and copy grunt's output directory to django's static and template dirs?

Or is there another way to make this work, the right one, I am missing?


回答1:


Your architecture is already clean, no need to make Django know about grunt or serve static files, and no need to use JS hacks to guess port numbers

Reverse Proxy

Use a reverse proxy like nginx or any other web server you like as a front end to both the static files and the REST API.

In computer networks, a reverse proxy is a type of proxy server that retrieves resources on behalf of a client from one or more servers. These resources are then returned to the client as though they originated from the proxy server itself. (Wikipedia)

I will outline the important aspects without going into too much detail:

URL for the REST API

We make configs so that nginx will forward the API requests to Django

location /api {
    proxy_pass http://127.0.0.1:8000;  # assumes Django listens here
    proxy_set_header Host $http_host;  # preserve host info
}

So the above assumes your Django REST is mapped to /api and runs on port 8000 (e.g. you can run gunicorn on that port, or any other server you like)

http://nginx.org/en/docs/http/ngx_http_proxy_module.html

URL for our front end app

Next nginx will serve the static files that come out of grunt, by simply pointing it to the static folder

location / { alias /app/static/; }

The above assumes your static resources are in /app/static/ folder (like index.html, your CSS, JS etc). So this is primarily to load your BackboneJS app.

Django static files

Next step is not required, but if you have static files that you use with the Django app (static files that are generated with ./manage.py collectstatic, e.g. the django admin or the UI of Django REST Framework etc), simply map according to your Django settings.py STATIC_URL and STATIC_ROOT

location /static { alias /app/django_static_root/; }

/static and django_static_root being the STATIC_URL and STATIC_ROOT respectively

To sum up

So e.g. when you hit example.com/, nginx simply serves up the static files, then when a JS script makes REST call to /api, it gets trapped in the /api nginx location and gets forwarded to Django

End result is, example.com/ and example.com/api both hit the same front end web server, which proxies them to the right places

So there you have it, reserve proxying solves your ports and subdomain issues (and many others, like slow static files from Django and same-origin policies in web browsers and firewalls not liking anything besides default HTTP and HTTPS ports)



来源:https://stackoverflow.com/questions/32148124/how-to-deploy-static-website-connecting-to-django-restful-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!