NAME
Plack::App::HostMap - Map multiple Plack apps by host
VERSION
version 0.002
SYNOPSIS
use Plack::App::HostMap;
my $foo_app = sub { ... };
my $bar_app = sub { ... };
my $baz_app = sub { ... };
my $host_map = Plack::App::HostMap->new;
#map different hosts to different apps
$host_map->map("www.foo.com" => $foo_app);
$host_map->map("bar.com" => $bar_app);
$host_map->map("test.baz.com" => $baz_app);
#map multiple hosts to same app conveniently
$host_map->map(["www.foo.com", "foo.com", "beta.foo.com"] => $foo_app);
#map all subdomains of a host to an app
$host_map->map("*.foo.com" => $foo_app); #will match www.foo.com, foo.com, beta.foo.com, test.foo.com, beta.test.foo.com, etc...
my $app = $host_map->to_app;
DESCRIPTION
Plack::App::HostMap is a PSGI application that can dispatch multiple applications based on host name (a.k.a "virtual hosting"). Plack::App::URLMap can also dispatch applications based on host name. However, it also more versatile and can dispatch applications based on URL paths. Because of this, if you were to use Plack::App::URLMap to map applications based on host name it would take linear time to find your app. So if you had N host name entries to map to apps, you might have to search through N mappings before you find the right one. Because Plack::App::HostMap is simpler and only dispatches based on host name, it can be much more efficient for this use case. Plack::App::HostMap uses a hash to look up apps by host name, and thus instead of a linear time lookup is constant time. So if you had 2 apps to dispatch by host name or 10,000, there shouldn't be a difference in terms of performance since hashes provide constant time lookup.
METHODS
map
$host_map->map("www.foo.com" => $foo_app);
$host_map->map("bar.com" => $bar_app);
Maps a host name to a PSGI application. You can also map multiple host names to one application at once by providing an array reference:
$host_map->map(["www.foo.com", "foo.com", "beta.foo.com"] => $foo_app);
If you need all subdomains of a host name to map to the same app, instead of listing them all out you can do so like this:
$host_map->map("*.foo.com" => $foo_app); #will match www.foo.com, foo.com, beta.foo.com, test.foo.com, beta.test.foo.com, etc...
This will map any subdomain of foo.com to $foo_app
. This way you can point new subdomains at your app without having to update your mappings.
mount
Alias for map
.
to_app
my $handler = $host_map->to_app;
Returns the PSGI application code reference. Note that the Plack::App::HostMap object is callable (by overloading the code dereference), so returning the object itself as a PSGI application should also work.
PERFORMANCE
As mentioned in the DESCRIPTION, Plack::App::HostMap should perform much more efficiently than Plack::App::URLMap when being used for host names. One caveat would be with the *.
syntax that can be used with map. If you have even just one mapping with a *.
in it:
$host_map->map("*.foo.com" => $foo_app);
Then on every request Plack::App::HostMap must call Domain::PublicSuffix's get_root_domain
subroutine to parse out the root domain of the host. I can't imagine that this is very costly, but maybe if you are receiving a lot of requests this could make a difference. If you find that to be the case, instead of using the *.
syntax you could list out each individual possibility:
$host_map->map("beta.foo.com" => $foo_app);
$host_map->map("www.foo.com" => $foo_app);
$host_map->map("foo.com" => $foo_app);
#or
$host_map->map(["beta.foo.com", "www.foo.com", "foo.com"] => $foo_app);
And the result would be that lookup is back to constant time. However, you might never see a performance hit and it might be more worth it to use the convenient syntax.
AUTHOR
Adam Hopkins <srchulo@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2014 by Adam Hopkins.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.