phpyii2

Manipulating the controller map for an API application


I have a set of extensions in my application (yii2-advanced) that have to be maintained in their own repos. To make them as detached as possible, they register as modules on their own and adds to the menu and migrations like this:

vendor\ext\Ext.php

namespace vendor\ext;

use yii\base\BootstrapInterface;

class ext implements BootstrapInterface
{
    public function bootstrap($app)
    {
        $this->addToMenu($app);
        $this->addToModules($app);
        $app->params['migrations'] = array_merge($app->params['migrations'], ['@vendor/ext/migrations']);
    }

    private function addToMenu($app)
    {
        ...
    }

    private function addToModules($app)
    {
    $app->setModule('ext', ['class' => 'vendor\ext\Module']);
    }
}

vendor\ext\composer.json

"extra": {
  "bootstrap": "vendor\\ext\\Ext"
},

This works very well, with the controllers in vendor\ext\controllers\. I have an extra application created as a REST API, and I need that application to access vendor\ext\api\ instead of vendor\ext\controllers\.

So if you'd access example.com/ext/controller you'd get vendor\ext\controllers\controller::index(), but if you'd access api.example.com/ext/controller you'd get vendor\ext\api\controller::index().

I've read trough the docs a lot to solve the bootstrapping functionalities that I have, but I can't seem to figure out this one.


Solution

  • I solved it by adding each API version as another module and register it with the corresponding version module of my API application.

    Now I can develop each module with its supported api versions in a separate repository and everything registers automatically.

    Posting the bootstrap code below if anyone needs do do something similar.

    public $supported_api_versions = [];
    
    public function bootstrap($app)
    {
        $this->addToMenu($app);
        if($app->id == 'app-frontend')
        {
            $this->addToModules($app);
        }
        elseif($app->id == 'app-backend')
        {
            // Add code here if the module should be available in backend application
        }
        elseif($app->id == 'app-api')
        {
            foreach ( $this->supported_api_versions as $api ) {
                $module = $app->getModule($api);
                $module->setModule($this->name, ['class' => 'vendor\\'.$this->name.'\api\\'.$api.'\Module']);
            }
        }
        elseif($app->id == 'app-console')
        {
            $app->params['migrations'] = array_merge($app->params['migrations'], ['@vendor/'.$this->name.'/migrations']);
        }
    }