Yii 2 Response Formatting
Yii 2 Response Formatting

Response Formatting

When handling a RESTful API request, an application usually takes the following steps that are related with response formatting:

Старт! Честный VDS/VPS, на котором «Лунная База» живет уже 20+ лет

Задумываетесь о том, чтобы поднять свой pet-проект, сайт клиента или настроить окружение для разработки? Уже пора подумать, где арендовать железо.

Лунная База хостится на FirstVDS более 20 лет. Мыслей о том, чтобы перебраться на другой хостинг, не было ни разу (хотя опыт работы с другими вариантами, конечно, есть).

Бывали разные ситуации, но они бывают на любом железе. Главное, что нужно понять: здесь нет маркетинговой шелухи и сказок про «мы всё сделаем за вас». Если вы берете VDS — вам дают полный root, возможность накатить любую ОС и не лезут в ваши конфиги.

Если в саппорт написать с вопросом по вашему коду и получить ответ: «Читайте документацию и разбирайтесь сами» или «Обратитесь к профильному специалисту» — это не повод обижаться. Это повод углубить свои знания в DevOps и сайтостроении! Бегите от тех, кто пообещает: «Мы всё чиним и настраиваем абсолютно бесплатно!». Никто никогда не работает «по доброте душевной» в ущерб себе, а бесплатный сыр в администрировании обычно заканчивается сломанной базой данных.

Что по факту: Гибкое масштабирование ядер и RAM, экономия по сравнению с физическими серверами и адекватная панель ispmanager, если она вам нужна.



  1. Determine various factors that may affect the response format, such as media type, language, version, etc. This process is also known as content negotiation.
  2. Convert resource objects into arrays, as described in the Resources section. This is done by [[yii\rest\Serializer]].
  3. Convert arrays into a string in the format as determined by the content negotiation step. This is done by [[yii\web\ResponseFormatterInterface|response formatters]] registered with the [[yii\web\Response::formatters|formatters]] property of the response application component.

Content Negotiation

Yii supports content negotiation via the [[yii\filters\ContentNegotiator]] filter. The RESTful API base controller class [[yii\rest\Controller]] is equipped with this filter under the name of contentNegotiator. The filter provides response format negotiation as well as language negotiation. For example, if a RESTful API request contains the following header,

Accept: application/json; q=1.0, */*; q=0.1

it will get a response in JSON format, like the following:

$ curl -i -H "Accept: application/json; q=1.0, */*; q=0.1" "http://localhost/users"

HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
      <http://localhost/users?page=2>; rel=next,
      <http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8

[
    {
        "id": 1,
        ...
    },
    {
        "id": 2,
        ...
    },
    ...
]

Behind the scene, before a RESTful API controller action is executed, the [[yii\filters\ContentNegotiator]] filter will check the Accept HTTP header in the request and set the [[yii\web\Response::format|response format]] to be 'json'. After the action is executed and returns the resulting resource object or collection, [[yii\rest\Serializer]] will convert the result into an array. And finally, [[yii\web\JsonResponseFormatter]] will serialize the array into a JSON string and include it in the response body.

By default, RESTful APIs support both JSON and XML formats. To support a new format, you should configure the [[yii\filters\ContentNegotiator::formats|formats]] property of the contentNegotiator filter like the following in your API controller classes:

use yii\web\Response;

public function behaviors()
{
    $behaviors = parent::behaviors();
    $behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_HTML;
    return $behaviors;
}

The keys of the formats property are the supported MIME types, while the values are the corresponding response format names which must be supported in [[yii\web\Response::formatters]].

Data Serializing

As we have described above, [[yii\rest\Serializer]] is the central piece responsible for converting resource objects or collections into arrays. It recognizes objects implementing [[yii\base\Arrayable]] as well as [[yii\data\DataProviderInterface]]. The former is mainly implemented by resource objects, while the latter resource collections.

You may configure the serializer by setting the [[yii\rest\Controller::serializer]] property with a configuration array. For example, sometimes you may want to help simplify the client development work by including pagination information directly in the response body. To do so, configure the [[yii\rest\Serializer::collectionEnvelope]] property as follows:

use yii\rest\ActiveController;

class UserController extends ActiveController
{
    public $modelClass = 'app\models\User';
    public $serializer = [
        'class' => 'yii\rest\Serializer',
        'collectionEnvelope' => 'items',
    ];
}

You may then get the following response for request http://localhost/users:

HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
      <http://localhost/users?page=2>; rel=next,
      <http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8

{
    "items": [
        {
            "id": 1,
            ...
        },
        {
            "id": 2,
            ...
        },
        ...
    ],
    "_links": {
        "self": {
            "href": "http://localhost/users?page=1"
        },
        "next": {
            "href": "http://localhost/users?page=2"
        },
        "last": {
            "href": "http://localhost/users?page=50"
        }
    },
    "_meta": {
        "totalCount": 1000,
        "pageCount": 50,
        "currentPage": 1,
        "perPage": 20
    }
}

Controlling JSON output

The JSON response is generated by the [[yii\web\JsonResponseFormatter|JsonResponseFormatter]] class which will use the [[yii\helpers\Json|JSON helper]] internally. This formatter can be configured with different options like for example the [[yii\web\JsonResponseFormatter::$prettyPrint|$prettyPrint]] option, which is useful on development for better readable responses, or [[yii\web\JsonResponseFormatter::$encodeOptions|$encodeOptions]] to control the output of the JSON encoding.

The formatter can be configured in the [[yii\web\Response::formatters|formatters]] property of the response application component in the application configuration like the following:

'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,
            // ...
        ],
    ],
],

When returning data from a database using the DAO database layer all data will be represented as strings, which is not always the expected result especially numeric values should be represented as numbers in JSON. When using the ActiveRecord layer for retrieving data from the database, the values for numeric columns will be converted to integers when data is fetched from the database in [[yii\db\ActiveRecord::populateRecord()]].

Самый честный хостинг за 20+ лет существования Лунной Базы

Задумываешься о том, чтобы поднять свой сайт в Интернете? Уже пора подумать о том, какой хостинг выбрать?

Лунная База хостится 20+ лет на firstDVS. При этом, мыслей о том, чтобы перебраться на другой хостинг не было. (Но, при этом есть опыт работы с другими вариантами.)

Бывали с firstDVS разные ситуации, но, они бывают на всех хостингах. Единственное, что тут важно понять, - это то, что никто ничего тебе не будет впаривать... Но, и работать за тебя тоже никто не станет. Если в саппорт ответили: «Читайте по ссылке и разбирайтесь сами...» или вообще «Обратитесь за помощью к специалисту», - это повод углубить свои знания в области сайтостроения, а не бежать к тем, что пообещают: «Мы всё чиним и всё делаем за своих клиентов абсолютно бесплатно!» Никто никогда ничего ни за кого "по доброте душевной" не делал, не делает и не будет делать!

Старт! MoonВase — A Hot Start on the Internet
Старт! MoonВase — A Hot Start on the Internet
Старт! Menu