Django subdomain configuration for API endpoints

丶灬走出姿态 提交于 2019-12-20 15:23:10

问题


I've set up a Django project which makes use of the django-rest-framework to provide some ReST functionality. The website and the rest functionality are all working fine.

However there is one little problem: I need my API endpoints to point to a different subdomain.

For example when a user visits the website he/she can navigate around normally according to my urls.py:

http://example.com/control_panel

So far so good. However when the API is used I want to change that to something more appropriate. So instead of http://example.com/api/tasks I need this to become:

http://api.example.com/tasks

How should I do that?

Thanks in advance.

P.S. The website will be running on Gunicorn with nginx serving as a reverse proxy.


回答1:


I had a similar issue with a Django based API. I found it useful to write a custom middleware class and use that to control which URLs were served on which subdomains.

Django doesn't really care about subdomains when serving URLs, so assuming your DNS is set up such that api.example.com points to your Django project, then api.example.com/tasks/ will call the expected API view.

The problem is that www.example.com/tasks/ would also call the API view, and api.example.com would serve the home page in a browser.

So a bit of middleware can check that subdomains match up with URLs and raise 404 responses if appropriate:

## settings.py

MIDDLEWARE_CLASSES += (
    'project.middleware.SubdomainMiddleware',
)


## middleware.py

api_urls = ['tasks']  # the URLs you want to serve on your api subdomain

class SubdomainMiddleware:
    def process_request(self, request):
        """
        Checks subdomain against requested URL.

        Raises 404 or returns None
        """
        path = request.get_full_path()  # i.e. /tasks/
        root_url = path.split('/')[1]  # i.e. tasks
        domain_parts = request.get_host().split('.')

        if (len(domain_parts) > 2):
            subdomain = domain_parts[0]
            if (subdomain.lower() == 'www'):
                subdomain = None
            domain = '.'.join(domain_parts[1:])
        else:
            subdomain = None
            domain = request.get_host()

        request.subdomain = subdomain  # i.e. 'api'
        request.domain = domain  # i.e. 'example.com'

        # Loosen restrictions when developing locally or running test suite
        if not request.domain in ['localhost:8000', 'testserver']:
            return  # allow request

        if request.subdomain == "api" and root_url not in api_urls:
            raise Http404()  # API subdomain, don't want to serve regular URLs
        elif not subdomain and root_url in api_urls:
            raise Http404()  # No subdomain or www, don't want to serve API URLs
        else:  
            raise Http404()  # Unexpected subdomain
        return  # allow request  



回答2:


What about django-dynamicsites-lite. And your code will be more clean because API and site are in different folders.



来源:https://stackoverflow.com/questions/28433536/django-subdomain-configuration-for-api-endpoints

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