PerlDancer/Dancer2 — pull request #677 by xsawyerx (2014-09-07 16:43:15+00:00)
Title: Major architectural change: Apps now dispatch independently as full-fledged PSGI apps

This is a resubmit of an older PR. This one handles complete backwards compatibility.

* Applications are now finalized to a full-fledged PSGI app:

They can now be used independently without the Dispatcher itself.
They can also be mixed independently without the Dispatcher.

You can do this using either the 'to_app' method on the App class
or the 'to_app' DSL.

If you want to create multiple Apps, you can use the following
mechanisms to control the flow:
* Plack::App::URLMap: mounting them on different prefixes.
* 'prefix' keyword: set different apps on different prefixes.
* Registering under the same 'appname': thus providing them
with the same engines.

The 'prefix' and 'appname' can be used together to provide
multiple Apps that share the same engines (sessions, for example)
but still retain different paths.

* The App-level dispatcher (new-style) is bound to an App:

If you're using 'to_app', it will only loop over routes within
that App. This major change causes 'forward' and 'pass' to only
work within the App that is created with 'to_app'. You will not
be able to forward or pass to routes outside that App.

Forwarding and passing between Applications is considered risky,
fragile, and a source of possible security problems. Although we
try to mitigate it, it shouldn't be done.

You can still use the old-style dispatcher - check the next
clause.

* The Dispatcher class (old-style) still works:

The regular Dancer2::Core::Dispatcher uses some hacks (which the
App helps with) in order to still provide the old style if you're
using the 'psgi_app' DSL.

With the new architecture you cannnot forward or pass requests
between Apps.

The way the current mechanism works is:
* The dispatching code has been moved to the App.
* If you decide to use the Dispatcher, it will simply loop over the
Apps and call each one just like a normal PSGI app. It will allow
the App to give hints so it could adjust the dispatching mechanism
to render in the old-style.

Notes:
* We could now allow each App to have its own allowed HTTP methods.
* We could now allow each App to have its own custom 500 error.
* We could now allow each App to decide whether to add the 'Head'
middleware or not.
* We could now control the middleware each App gets separately.
* We could now easily add pure PSGI responses.
* We could start working on a nice DSL for delayed PSGI responses.