We need to serve the wadl and json conditionally based on the Accept request header. http://httpd.apache.org/docs/current/content-negotiation.html (http://httpd.apache.org/docs/current/mod/mod_negotiation.html) seems to handle that fine. The type-map approach would mean that we would need to have explicit type maps for each version of the api. While we freeze the API infrequently enough that this will probably not be a problem often, it would be nice if we could make a solution that was static within our Apache configuration, and the other Apache approach, multiviews, does that. Here's my understanding so far of what to do, then. We probably need this in /etc/apache2/mods-enabled/mime.conf (http://httpd.apache.org/docs/current/mod/mod_mime.html). AddType application/vd.sun.wadl+xml .wadl This too. AddType application/json .json Our wadl generation would be changed. Right now it creates wadl-development-1.0.xml, wadl-development-beta.xml and wadl-development-devel.xml in lib/canonical/launchpad/apidoc . Instead we'd create a structure like this. version/index.[wadl|json] In other words, for the three revisions we have now, you'd see beta/index.wadl beta/index.json 1.0/index.wadl 1.0/index.json devel/index.wadl devel/index.json Maybe we'd also symlink the .json to .txt in case we have a json client that sends the wrong mime type. I'd put it in lib/canonical/launchpad/apidoc because it won't be served the same as icing, and because people are used to finding it there. I think the apidoc stuff needs to be by itself in any case. In our Apache Launchpad site config for production, equivalent to /etc/apache2/sites-enabled/local-launchpad locally, we would want a new section that turned on MultiViews. Something like this might work: ServerName api.launchpad.dev Order deny,allow Allow from 127.0.0.0/255.0.0.0 SSLEngine On SSLCertificateFile /etc/apache2/ssl/launchpad.crt SSLCertificateKeyFile /etc/apache2/ssl/launchpad.key ProxyPassMatch ^(/[^/]+/.+)$+ http://localhost:8086/$1 retry=1 DocumentRoot /var/tmp/api.launchpad.dev/static/ Options MultiViews DirectoryIndex index # Insert filter SetOutputFilter DEFLATE # Don't compress images SetEnvIfNoCase Request_URI \ \.(?:gif|jpe?g|png)$ no-gzip dont-vary # Don't gzip anything that starts /@@/ and doesn't end .js (ie images) SetEnvIfNoCase Request_URI ^/@@/ no-gzip dont-vary SetEnvIfNoCase Request_URI ^/@@/.*\.js$ !no-gzip !dont-vary I'm not sure what we would really do for dev boxes. We could do what +icing does now, and defer to Zope when you are on the dev, and implement the same kind of behavior in Zope; or, as implied in the snippet above, we could make starting an instance stuff a symlink from the current tree's lib/canonical/launchpad/apidoc into /var/tmp/api.launchpad.dev/static/ for when you run in devel or testing mode. The desire to continue to use ETags would be a little trickier, given load balanced servers. Apache by default incudes the inode in the etag calculation (http://httpd.apache.org/docs/current/mod/core.html#fileetag), which will vary. If modified time is synchronized across our servers for these files, then FileETag MTime Size would probably work great. Otherwise...we might have to go to a drawingboard. The ETag optimization was a big one for many of our users, in my memory. Now that I've researched what I think might work, I'll look for comments on this now.