Yii2 framework backup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

5.7 KiB

Dando Formato a la Respuesta

Cuando se maneja una petición al API RESTful, una aplicación realiza usualmente los siguientes pasos que están relacionados con el formato de la respuesta:

  1. Determinar varios factores que pueden afectar al formato de la respuesta, como son el tipo de medio, lenguaje, versión, etc. Este proceso es también conocido como Negociación de contenido (content negotiation).
  2. La conversión de objetos recursos en arrays, está descrito en la sección Recursos (Resources). Esto es realizado por el serializador yii\rest\Serializer.

Tip: Serializar es convertir un elemento a un formato que nos permita guardardarlo de forma permanente, de modo que posteriormente, al recuperarlo, nos de una copia igual a la del elemento antes de ser inicialmente serializado.

  1. La conversión de arrays en cadenas con el formato determinado por el paso de negociación de contenido. Esto es realizado por yii\web\ResponseFormatterInterface registrado con el componente de la aplicación yii\web\Response::formatters.

Negociación de contenido (Content Negotiation)

Yii soporta la negoiciación de contenido a través del filtro yii\filters\ContentNegotiator. La clase controladora base del API RESTful yii\rest\Controller está equipada con este filtro bajo el nombre contentNegotiator. El filtro provee tanto un formato de respuesta de negociación como una negociación de lenguaje. Por ejemplo, si la petición API RESTful contiene la siguiente cabecera,

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

puede obtener una respuesta en formato JSON, como lo que sigue:

$ 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,
        ...
    },
    ...
]

En la parte de atrás, antes de que sea ejecutada una acción de la controladora del API RESTful, el filtro yii\filters\ContentNegotiator comprobará en la cabecera HTTP el Accept de la petición y pondrá como 'json' yii\web\Response::format. Después de que la acción sea ejecutada y devuelva el recurso objeto resultante o una colección resultante, yii\rest\Serializer convertirá el resultado en un array. Y finalmente, yii\web\JsonResponseFormatter serializará el array en una cadena JSON incluyéndola en el cuerpo de la respuesta.

Por defecto, el API RESTful soporta tanto el formato JSON como el XML. Para soportar un nuevo formato, debes configurar la propiedad yii\filters\ContentNegotiator::formats del filtro contentNegotiator tal y como sigue, en las clases de la controladora del API:

use yii\web\Response;

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

Las claves de la propiedad formats son los tipos MIME soportados, mientras que los valores son los nombre de formato de respuesta correspondientes, los cuales han de estar soportados en yii\web\Response::formatters.

Serialización de Datos

Como hemos descrito antes, yii\rest\Serializer es la pieza central para convertir recursos objeto o colecciones en arrays. Reconoce objetos tanto implementando yii\base\ArrayableInterface como yii\data\DataProviderInterface. El primer formateador es implementado principalmente para recursos objeto, mientras que el segundo para recursos collección.

Puedes configurar el serializador poniendo la propiedad yii\rest\Controller::serializer con un array de configuración. Por ejemplo, a veces puedes querer simplificar la ayuda al trabajo de desarrollo del cliente incluyendo información de la paginación directamente en el cuerpo de la respuesta. Para hacer esto, configura la propiedad yii\rest\Serializer::collectionEnvelope como sigue:

use yii\rest\ActiveController;

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

Puedes obtener la respuesta que sigue para la petición 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": "http://localhost/users?page=1",
        "next": "http://localhost/users?page=2",
        "last": "http://localhost/users?page=50"
    },
    "_meta": {
        "totalCount": 1000,
        "pageCount": 50,
        "currentPage": 1,
        "perPage": 20
    }
}