title: ZF2 router configuration for handling multiple subdomains
body: <p>I'm working on a zf2 project and i need to configure some of my modules to work on different subdomains following scenario:</p>
  
  <ul>
  <li>I have different Modules like API, Backend (Admin), Application (Core
  module), Blog etc..</li>
  <li>I have multiple vhosts which points to same
  application/public directory like api.foobar.com, admin.foobar.com</li>
  <li>I'm using unique controller keys/aliases in each module like this:</li>
  </ul>
  
  <p>...</p>
  
  <pre><code>'controllers' =&gt; array(
      'invokables' =&gt; array(
          'home-controller'     =&gt; 'Application\Controller\IndexController',
      ),
  ),
  </code></pre>
  
  <p>So, i want to change my application's behaviour based on domain (hostname/routeMatch), if hostname looks like api.foobar.com my default controller should derived form a restful controller, if it's a generic homepage request my auth-backed admin controller should not invoke, if it's a mobile site, change home controller to mobile-controller, utilize different layout etc...</p>
  
  <p>Non-working configuration (application/config/module.config.php):</p>
  
  <pre><code>return array(
      'router' =&gt; array(
          'routes' =&gt; array(
             'home' =&gt; array(
                  'type' =&gt; 'hostname',
                  'options' =&gt; array(
                      'route' =&gt; 'www.foobar.com',
                      'defaults' =&gt; array(
                          '__NAMESPACE__' =&gt; 'Application\Controller',
                          'controller' =&gt; 'home-controller',
                          'action' =&gt; 'index'
                      )
                  )
              ),
              'api' =&gt; array(
                  'type' =&gt; 'hostname',
                  'options' =&gt; array(
                      'route' =&gt; 'api.foobar.com',
                      'constraints' =&gt; array(
                          'subdomain' =&gt; 'api',
                      ),
                      'defaults' =&gt; array(
                          '__NAMESPACE__' =&gt; 'Api\Controller',
                          'controller' =&gt; 'api-controller',
                          'action' =&gt; 'index'
                      )
                  )
              ),
              'admin' =&gt; array(
                  'type' =&gt; 'hostname',
                  'options' =&gt; array(
                      'route' =&gt; 'admin.foobar.com',
                      'constraints' =&gt; array(
                          'subdomain' =&gt; 'admin',
                      ),
                      'defaults' =&gt; array(
                          '__NAMESPACE__' =&gt; 'Admin\Controller',
                          'controller' =&gt; 'admin-controller',
                          'action' =&gt; 'index'
                      )
                  ),
                  'may_terminate' =&gt; true,
                  'child_routes' =&gt; array(
                      'default' =&gt; array(
                          'type' =&gt; 'Segment',
                          'options' =&gt; array(
                              'route' =&gt; '/[:controller[/:action]]',
                              'constraints' =&gt; array(
                                  '__NAMESPACE__' =&gt; 'Admin\Controller',
                                  'controller' =&gt; '[a-zA-Z][a-zA-Z0-9_-]*',
                                  'action' =&gt; '[a-zA-Z][a-zA-Z0-9_-]*'
                              ),
                              'defaults' =&gt; array()
                          )
                      )
                  )
              )
          )
      )
  );
  </code></pre>
  
  <p>Interesting thing is, currently with this configuration i'm getting a 404 page not found error both api.foobar.com, www.foobar.com and admin.foobar.com on my devlepment environment and dump of routes like following:</p>
  
  <pre><code>object(Zend\Mvc\Router\PriorityList)[214]
    protected 'routes' =&gt; 
      array (size=3)
        'home' =&gt; 
          array (size=3)
            'route' =&gt; 
              object(Zend\Mvc\Router\Http\Hostname)[216]
                ...
            'priority' =&gt; int 0
            'serial' =&gt; int 0
        'admin' =&gt; 
          array (size=3)
            'route' =&gt; 
              object(Zend\Mvc\Router\Http\Part)[218]
                ...
            'priority' =&gt; int 0
            'serial' =&gt; int 1
                ...
            'priority' =&gt; int 0
            'serial' =&gt; int 2
    protected 'serial' =&gt; int 3
    protected 'count' =&gt; int 3
    protected 'sorted' =&gt; boolean false
  </code></pre>
  
  <blockquote>
    <p>I got this dump in Application Module > Module.php > onBootstrap($e) method simply: 
    $routes = $e->getApplication()->getServiceManager->get('router')->getRoutes();</p>
  </blockquote>
  
  <p>Questions:</p>
  
  <ol>
  <li>What is wrong with this configration?</li>
  <li>why my top-level <strong>admin route</strong> listing as a <strong>Zend\Mvc\Router\Http\Part</strong>?</li>
  <li>Should i separate route definitions to every module's own module.config.php file for this scenario?</li>
  </ol>