Last Updated: February 25, 2016
·
318
· kordless

Handling Subdomain Routes with AppEngine

I've been using GAE-Boilerplate for several projects including the code here on StackGeek. GAEB uses webapp2 for it's application framework. Recently, while trying to solve a security concern with utter.io, I went in search of a way to route subdomains to different handlers.

Subdomain Handling

Webapp2 provides a method called DomainRoute which takes a subdomain as an argument and uses it to match a set of routes you pass to it. Here's a snippet of that in action:

routes = [
    # handle specific subdomain/hostname
    DomainRoute(config.subdomain_hostname, [
        Route('/', handler='handlers.PageHandler:subdomain', name='pages-subdomain'),
    ]),

    # handle other hostnames and domains
    Route('/', handler='handlers.PageHandler:root', name='pages-root'),
]

Try It Out

You can clone my example repo and add it to AppEngine Launcher to test the code. Check out the code locally by doing the following:

git clone git://github.com/kordless/webapp2-starter.git

You'll also need to modify your local hosts file for testing. Add the following to the bottom of your /etc/hosts file:

sublocalhost 127.0.0.1

Add the new project by going to File..Add Existing Application and browsing to the directory where you checked it out. Be sure to set the port to 8282 if you want to use the links I provide below.

screenshots

Click on add. Click on the run button to start the app. You should now be able to hit the following urls:

Notice you get different results for the two pages.

Production Configuration

For this to work in production on AppEngine, you'll need to add the full subdomain+domain to Google Apps. In the screenshot below, I've added a subdomain oi.utter.io to the utter.io domain I configured the first time through domain setup for my AppEngine project.

google_apps

Now I'm in production, my config file looks like this:

# config file
if os.environ['SERVER_SOFTWARE'].startswith('Dev'):
    subdomain_hostname = 'sublocalhost'
else:
    subdomain_hostname = 'oi.utter.io'

With this technique I've been able to keep the code in a single repository, deployed to a single AppEngine project, yet serve two distinct subdomains. Very handy!