HTTP requests from users can reach the appropriate module/version/instance in two ways: A request with a URL that ends at the domain level can be routed according to App Engine's default address routing rules. Alternatively, you can include a dispatch file that routes specific URL patterns according to your own rules.
If you test your app using the
development server
the available routing and dispatch features are slightly different.
To programmatically create URLs that work with both production and
development servers, use the
appengine.ModuleHostname
function.
See
routing in the development server
to learn more.
Addressing instances
You can target an HTTP request with varying degrees of specificity. In the following examples appspot.com can be replaced with your app's custom domain if you have one. The URL substrings "instance", "version", "module", and "app-id" represent application and module attributes that you have defined yourself.
These two address forms are guaranteed to reach their target (if it exists). They will never be intercepted and rerouted by a pattern in the dispatch file:
http://instance.version.module.app-id.appspot.com
- Sends a request to the named module, version, and instance. This address form can only be used by application administrators.
http://version.module.app-id.appspot.com
- Send the request to an available instance of the named module and version (round robin scheduling is used).
These address forms have a default routing behavior. Note that the default routing is overridden if there is a matching pattern in the dispatch file:
http://module.app-id.appspot.com
- Send the request to an available instance of the default version of the named module (round robin scheduling is used).
http://version.app-id.appspot.com
- Send the request to an available instance of the given version of the default module.
http://app-id.appspot.com
- Send the request to an available instance of the default version of the default module.
The default module is defined by explicitly giving a module the name "default," or by not including the name parameter in the module's config file. Requests that specify no module or an invalid module are routed to the default module. You can use the Admin Console to designate a default version for a module, when appropriate.
All modules are public by default, if you want to restrict access to a module, add the “login: admin” parameter to its handlers.
Please note that in April of 2013, Google stopped issuing SSL certificates for double-wildcard domains hosted at
appspot.com
(i.e.
*.*.appspot.com
). If you rely on such URLs for HTTPS access to your application, please change any application logic to use "-dot-" instead of ".". For example, to access version "1" of application "myapp" use "https://1-dot-myapp.appspot.com" instead of "https://1.myapp.appspot.com." If you continue to use "https://1.myapp.appspot.com" the certificate will not match, which will result in an error for any User-Agent that expects the URL and certificate to match exactly.
Dispatch file
You can create a dispatch file to override the default routing for URLs that do not specify a version (described above). This lets you route incoming requests to a specific module based on the path or hostname in the URL. For example, say that you want to route mobile requests like
http://simple-sample.appspot.com/mobile/
to a mobile frontend, route worker requests like
http://simple-sample.appspot.com/work/
to a static backend, and serve all static content from the default module.
To do this you can create a custom routing with a
dispatch.yaml
file.
application: simple-sample
# No version required, this does routing independent of version
dispatch:
# Default module serves the typical web resources and all static resources.
- url: "*/favicon.ico"
module: default
# Default module serves simple hostname request.
- url: "simple-sample.appspot.com/"
module: default
# Send all mobile traffic to the mobile frontend.
- url: "*/mobile/*"
module: mobile-frontend
# Send all work to the one static backend.
- url: "*/work/*"
module: static-backend
The dispatch file can contain up to 10 routing rules. When specifying the url string, neither the hostname nor the path can be longer than 100 characters.
As you can see,
dispatch.yaml
includes support for glob characters (however, yaml syntax requires that you include such expressions in quotes to denote they are strings). Glob characters can be used only before the hostname and at the end of the path. If you prefer general routing rules that match many possible requests, you could specify the following:
# Send any path that begins with “simple-sample.appspot.com/mobile” to the mobile-frontend module.
- url: "simple-sample.appspot.com/mobile*"
module: mobile-frontend
# Send any domain/sub-domain with a path that starts with “work” to the static backend module.
- url: "*/work*"
module: static-backend
You can also write expressions that are more strict:
# Matches the path "/fun", but not "/fun2" or "/fun/other"
- url: "*/fun"
module: mobile-frontend
# Matches the hostname 'customer1.myapp.com', but not '1.customer1.myapp.com.
- url: "customer1.myapp.com/*"
module: static-backend
Note that you must use
appcfg
to deploy the
dispatch.yaml
file (
goapp
cannot deploy this file):
cd simple-sample
appcfg.py [--oauth2] update_dispatch .
Routing in the development server
Addressing instances
The development server creates all manual scaling instances at startup. Instances for automatic and basic scaling modules are managed dynamically. The server assigns a port to each module, so clients can depend on the server to load-balance and select an instance automatically. The port assignments for addressing each module appear in the server's log message stream. Here are the ports for an app that defines three modules, the scaling type of each module is not relevant:
INFO Starting module "default" running at: http://localhost:8084
INFO Starting module "module1" running at: http://localhost:8082
INFO Starting module "module2" running at: http://localhost:8083
When you use a module's address (for example
http://localhost:8082/
),
the server will select (or create) an instance of the module and send the
request to that instance.
The server assigns unique ports to each instance of a module. To discover these ports you need to use the admin server. There is a unique port for the admin server, it appears in the message log:
INFO Starting admin server at: http://localhost:8000
This address takes you to the admin server console. From there you can click on Instances to see the dynamic state of your app's instances:
A separate entry will appear for each manual and basic instance. The instance numbers are links with unique port addresses for each instance. You can hover over a link to see the port assigned to that instance, or click on the link to send a request directly to that instance.
Dispatch files
If your app uses a
dispatch.yaml
file, the log messages stream will
include a dispatcher port:
INFO Starting dispatcher running at: http://localhost:8080
Requests to this port will be routed according to the rules in the dispatch
file. The server does not support
dispatch.yaml
file rules that include
hostnames (for example,
url: "customer1.myapp.com/*"
). Rules with
relative path patterns (
url: "*/fun"
) will work, so you can use
URLs like
http://localhost/fun/mobile
to reach instances. The server will
report an error in the log stream if you try to start an application with a
dispatch.yaml
file that contains host-based rules.
Dispatch files and cron files
A routing conflict can occur if your app has a dispatch file and a
cron.yaml
file, and the same URL path appears in both files. The cron file
may specify a target module that is not the same as the module associated with
the URL in the dispatch file. When the cron job runs, the URL is routed via the
dispatch file, and the module specified there overrides the
target in the cron file.