phpyii2yii2-api

Yii2 - API Rest - ActiveDataProvider


I am building a REST API using Yii2 Basic Template. I am getting an error:

exception 'yii\base\InvalidArgumentException' with message 'Response content must be a string or an object implementing __toString().' in /Users/aurasix/ASX-Startups/ASX-CMS/asx-api-yii/vendor/yiisoft/yii2/web/Response.php:1062

Copy Stacktrace Search Stackoverflow Search Google Exception
Invalid Argument – yii\base\InvalidArgumentException
Response content must be a string or an object implementing __toString().

I am following the guide on yii2 website: https://www.yiiframework.com/doc/guide/2.0/en/rest-resources

Trying to use collections, in order to use pagination and ordering in the future, am I missing something?

I understand that if I use ActiveController probably this will be easier but I want to understand the full process that is why I am using Controller. Also I want full control, I think ActiveController will publish all methods just by defining the model, right?

My controller I am not extending it from ActiveController but from Controller

namespace app\modules\v1\controllers;

use yii\web\Controller;
use app\modules\v1\models\Blog;
use yii\data\ActiveDataProvider;

class BlogController extends Controller {

    public $serializer = [
        'class' => 'yii\rest\Serializer',
        'collectionEnvelope' => 'items',
    ];

    public function actionIndex() {
        return new ActiveDataProvider([
            'query' => Blog::find()
        ]);
    }

}

My model:

namespace app\modules\v1\models;

use yii\db\ActiveRecord;
use yii\web\Linkable;

class Blog extends ActiveRecord implements Linkable {

    public static function tableName() {
        return 'blog_post';
    }

    public function fields() {
        return [
            'id',
            'slug',
            'title',
            'full_content'
        ];
    }

    public function extraFields() {
        return [
            'publish_date',
            'short_content'
        ];
    }

    public function getLinks() {
        return [

        ];
    }

}

In config.php

'response' => [
            'formatters' => [
                \yii\web\Response::FORMAT_JSON => [
                    'class' => 'yii\web\JsonResponseFormatter',
                    'prettyPrint' => YII_DEBUG, // use "pretty" output in debug mode
                    'encodeOptions' => JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE,
                ],
            ],
        ],
'urlManager' => [
            'enablePrettyUrl' => false,
            'showScriptName' => false,
            'rules' => [
                [
                    'class' => 'yii\rest\UrlRule',
                    'controller' => 'v1/blog',
                    'pluralize'=>false
                ]
            ],
        ]

Solution

  • You should probably use yii\rest\Controller as a base controller class. It will not do all the magic for you like yii\rest\ActiveController do, but it contains some basic request filtering and response formatting features.

    yii\web\Controller does not contain $serializer property, it will not serialize your action response, so you cannot return ActiveDataProvider in action method. You should look to yii\rest\Controller source code - it uses afterAction() to serialize ActiveDataProvider returned from action. Without it you cannot configure serializer via $serializer property or return ActiveDataProvider in action method.