Best way to create base Controller

I have a requirement to create base controller. On low level I have to execute customized actions based on input JSON, get deal with stdinput and send JSON (and only json) responses. Unformtutaly I can’t do it from WebController layer as actions are executed on level below.
Once I get tried to create own BaseController - yii do not allow to run it because it should be instance of base name space (part of core Yii)
So my question is - what is the best practices here? How I can create baseController to use it as underlayer for WebController?

Normally you would define a \app\components\BaseController extends \yii\web\controllers, and then make all your other controllers inherit from it.

But I’m not sure I’m getting your question right.

You can achieve that by conditionally executing controller actions via yii\base\Controller::run

Have a look at the guide regarding content negotiation:

What do you mean by that?

Ultimately the following Controller should be sufficient for your needs. If not please go into more detail on what you want to achieve.


namespace app\controllers;

use Yii;
use yii\web\BadRequestHttpException;

class DispatchController extends \yii\rest\Controller
    public function actionIndex()
        $payload = Yii::$app->request->getBodyParams();

        if (!isset($payload['action'])) {
            throw new BadRequestHttpException();

        $params = $payload['params'] ?? [];
        return $this->run($payload['action'], $params);

    public function actionTest($echo)
        return $echo;

    protected function verbs()
        return ['index' => ['POST']];

In order for the above controller to work as expected you need to configure your web application to automatically parse JSON content for you:


// ...
'components' => [
  // ...
  'request' => [
    // ...
    'parsers' => [
      'application/json' => 'yii\web\JsonParser',

The controller can be used like this:

curl -X POST \
  -H  "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"action": "test", "params": ["This is passed to Dispatch::actionTest as paramater"] }' \

Response will be
"This is passed to Dispatch::actionTest as paramater"

I was under same impression as well, but I faced issue

Invalid Configuration – [yii\base\InvalidConfigException]

Controller class must extend from \yii\base\Controller.

once get tried to create own BaseController