Advertisement
  1. Code
  2. PHP
  3. Yii

Programando Con Yii2: Construyendo una API RESTful

Scroll to top
Read Time: 7 min
This post is part of a series called How to Program With Yii2.
How to Program With Yii2: Running Cron Services
Programming With Yii2: Building Community With Voting, Comments, and Sharing

() translation by (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

En esta serie Programando Con Yii2, estoy guiando a los lectores en el uso del Framework Yii2 para PHP. Podrías también estar interesado en mi Introducción al Framework Yii, que revisa los beneficios de Yii e incluye una vista general de las novedades en Yii 2.x.

En el tutorial de hoy, revisaré cómo construir una API REST en Yii para conectar tu aplicación a la nube, aplicaciones móviles, y otros servicios. Te guiaré a través de la guía de inicio rápido API REST y proporcionaré contexto y ejemplos de peticiones comunes.

Comenzando Con APIs REST Yii

Construir APIs REST en Yii es de hecho bastante sencillo. Puedes aprovechar el framework MVC existente, pero estás creando un punto de acceso distinto al que pretendes que sea accedido por diferentes tipos de servicios (no visitantes de sitio web).

Los Beneficios del Framework Yii REST

El Framework Yii proporciona soporte amplio y detallada documentación para construir APIs. Aquí hay algunas de las capacidades integradas cuando se construyen APIs:

  • Prototitpado rápido con soporte para APIs comunes para Active Record. Esto te permite exponer rápida y fácilmente funcionalidad de modelo de datos CRUD vía una API.
  • Respuesta formato negociación (soportando JSON y XML por defecto). Hay soporte integrado para devolver información en formatos comunes de salida.
  • Serialización personalizada de objeto con soporte para campos seleccionables de salida. Es sencillo modificar qué datos son devueltos.
  • Formato apropiado de colección de datos y validación de errores.
  • Soporte para Hypermedia Como El Motor de Estado de Aplicación (HATEOAS)
  • Ruteo eficiente con revisión apropiada de verbo HTTP.
  • Soporte integrado para los verbos OPTIONS y HEAD.
  • Autenticación y autorización.
  • Cacheo de datos y cacheo HTTP.
  • Limitación de tasa.

No tendré oportunidad de tocar todo esto el día de hoy.

Mi Interés en APIs REST

En este episodio, construiré una API para permitirnos manipular la tabla Item que creé en el servicio Twixxr desde este tutorial Twitter API. Pero también estoy planeando construir una API para nuestro enfoque de serie de tutoriales startup, Meeting Planner. Una API segura será necesaria para construir una aplicación iOS para el servicio. La API habilitará comunicación entre la aplicación móvil y el servicio en la nube.

Construyendo el Controlador REST

Con el framework REST de Yii, crearemos un punto final para nuestra API y organizaremos controladores para cada tipo de recurso.

Los recursos son esencialmente los modelos de datos de nuestra aplicación. Estos extienden a yii/base/Model.

La clase yii\rest\UrlRule proporciona mapear por ruteo nuestro modelo de datos para puntos finales CRUD API:

Programming Yii2 REST API UrlRule Documentation of CRUD API endpointsProgramming Yii2 REST API UrlRule Documentation of CRUD API endpointsProgramming Yii2 REST API UrlRule Documentation of CRUD API endpoints

Creando un Árbol para Actuar como una API Endpoint

En la plantilla Avanzada Yii2, hay un árbol front-end y back-end, y este es extensible. Para separar las características API, crearemos un tercer árbol para actuar únicamente como un punto final API.

El desarrollador Alex Makarov proporciona esta útil guía para crear árboles adicionales que seguí para crear mi tercer árbol:

1
$ cp -R backend api
2
$ cp -R environments/dev/backend/ environments/dev/api
3
$ cp -R environments/prod/backend/ environments/prod/api

Después, usé el editor Atom para hacer una búsqueda global y reemplazar "backend" con "api" en el nuevo árbol api.

Y agregué el alias de api a /common/config/bootstrap.php:

1
<?php
2
Yii::setAlias('@common', dirname(__DIR__));
3
Yii::setAlias('@frontend', dirname(dirname(__DIR__)) . '/frontend');
4
Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend');
5
Yii::setAlias('@api', dirname(dirname(__DIR__)) . '/api');
6
Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console');
7
Yii::setAlias('@twixxr', dirname(dirname(__DIR__)) . '/twixxr');

Configurando el ruteo de URL para Peticiones Entrantes

En /api/config/main.php, necesitamos agregar el request[] para configurar análisis JSON y UrlRule para asociar métodos para los modelos y sus puntos finales.

1
return [
2
    'id' => 'app-api',
3
    'basePath' => dirname(__DIR__),
4
    'controllerNamespace' => 'api\controllers',
5
    'bootstrap' => ['log'],
6
    'modules' => [],
7
    'components' => [
8
      'request' => [
9
        'parsers' => [
10
          'application/json' => 'yii\web\JsonParser',
11
        ],
12
      ],
13
      'urlManager' => [
14
        'enablePrettyUrl' => true,
15
        'enableStrictParsing' => true,
16
        'showScriptName' => false,
17
        'rules' => [
18
          ['class' => 'yii\rest\UrlRule', 'controller' => 'item'],
19
          ['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
20
        ],
21
      ],

Eso es básicamente lo que toma habilitar algo de funcionalidad API rica para estos modelos.

Ejemplos Con cURL

Comencemos a hacer peticiones.

Pidiendo OPTIONS

Muéstrame métodos API disponibles:

1
curl -i -H "Accept: application/json" 
2
    -X OPTIONS "http://localhost:8888/api/items"

Aquí está la respuesta (GET, POST, HEAD, OPTIONS):

1
HTTP/1.1 200 OK
2
Date: Tue, 25 Oct 2016 20:23:10 GMT
3
Server: Apache/2.2.31 (Unix) mod_wsgi/3.5 Python/2.7.12 PHP/7.0.10 mod_ssl/2.2.31 OpenSSL/1.0.2h DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0
4
X-Powered-By: PHP/7.0.10
5
Allow: GET, POST, HEAD, OPTIONS
6
Content-Length: 0
7
Content-Type: application/json; charset=UTF-8

Peticiones GET

Petición: ¿Cuántos datos hay ahí?

1
curl -i --head  "http://localhost:8888/api/items"

Respuesta: 576 registros a lo largo de 29 páginas...

1
HTTP/1.1 200 OK
2
Date: Tue, 25 Oct 2016 23:17:37 GMT
3
Server: Apache/2.2.31 (Unix) mod_wsgi/3.5 Python/2.7.12 PHP/7.0.10 mod_ssl/2.2.31 OpenSSL/1.0.2h DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0
4
X-Powered-By: PHP/7.0.10
5
X-Pagination-Total-Count: 576
6
X-Pagination-Page-Count: 29
7
X-Pagination-Current-Page: 1
8
X-Pagination-Per-Page: 20
9
Link: <http://localhost:8888/api/items?page=1>; rel=self, <http://localhost:8888/api/items?page=2>; rel=next, <http://localhost:8888/api/items?page=29>; rel=last
10
Content-Type: application/json; charset=UTF-8

Petición: Muéstrame el registro 15:

1
curl -i  "http://localhost:8888/api/items/15"

Respuesta:

1
HTTP/1.1 200 OK
2
Date: Tue, 25 Oct 2016 23:19:27 GMT
3
Server: Apache/2.2.31 (Unix) mod_wsgi/3.5 Python/2.7.12 PHP/7.0.10 mod_ssl/2.2.31 OpenSSL/1.0.2h DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0
4
X-Powered-By: PHP/7.0.10
5
Content-Length: 203
6
Content-Type: application/json; charset=UTF-8
7
8
{"id":15,"title":"Jeff Reifman","path":"jeffreifman",
9
"detail":"","status":0,"posted_by":1,"image_url":"",
10
"favorites":0,"stat_1":0,"stat_2":0,"stat_3":0,"created_at":1477277956,"updated_at":1477277956}

Petición: Muéstrame todos los datos en la página 3:

1
curl -i -H "Accept:application/json"
2
    "http://localhost:8888/api/items?page=3"

Respuesta:

1
HTTP/1.1 200 OK
2
Date: Tue, 25 Oct 2016 23:30:21 GMT
3
Server: Apache/2.2.31 (Unix) mod_wsgi/3.5 Python/2.7.12 PHP/7.0.10 mod_ssl/2.2.31 OpenSSL/1.0.2h DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0
4
X-Powered-By: PHP/7.0.10
5
X-Pagination-Total-Count: 575
6
X-Pagination-Page-Count: 29
7
X-Pagination-Current-Page: 3
8
X-Pagination-Per-Page: 20
9
Link: <http://localhost:8888/api/items?page=3>; rel=self, <http://localhost:8888/api/items?page=1>; rel=first, <http://localhost:8888/api/items?page=2>; rel=prev, <http://localhost:8888/api/items?page=4>; rel=next, <http://localhost:8888/api/items?page=29>; rel=last
10
Content-Length: 3999
11
Content-Type: application/json; charset=UTF-8
12
13
[{"id":43,"title":"_jannalynn","path":"_jannalynn",
14
"detail":"","status":0,"posted_by":1,"image_url":"",
15
"favorites":0,"stat_1":0,"stat_2":0,"stat_3":0,
16
...
17
...
18
...
19
{"id":99,"title":"alibrown","path":"alibrown","detail":"",
20
"status":0,"posted_by":1,"image_url":"","favorites":0,
21
"stat_1":0,"stat_2":0,"stat_3":0,"created_at":1477277956,
22
"updated_at":1477277956}]

Peticiones DELETE

Aquí está un ejemplo de una petición GET seguida por una petición DELETE y después un seguimiento fallido de intento GET: 

1
$ curl -i -H "Accept: application/json" "http://localhost:8888/api/items/8"
2
HTTP/1.1 200 OK
3
Date: Tue, 25 Oct 2016 23:32:17 GMT
4
Server: Apache/2.2.31 (Unix) mod_wsgi/3.5 Python/2.7.12 PHP/7.0.10 mod_ssl/2.2.31 OpenSSL/1.0.2h DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0
5
X-Powered-By: PHP/7.0.10
6
Content-Length: 186
7
Content-Type: application/json; charset=UTF-8
8
9
{"id":8,"title":"aaker","path":"aaker","detail":"","status":0,"posted_by":1,"image_url":"","favorites":0,"stat_1":0,"stat_2":0,"stat_3":0,"created_at":1477277956,"updated_at":1477277956}
10
11
$ curl -i -H "Accept: application/json" -X DELETE "http://localhost:8888/api/items/8"
12
HTTP/1.1 204 No Content
13
Date: Tue, 25 Oct 2016 23:32:26 GMT
14
Server: Apache/2.2.31 (Unix) mod_wsgi/3.5 Python/2.7.12 PHP/7.0.10 mod_ssl/2.2.31 OpenSSL/1.0.2h DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0
15
X-Powered-By: PHP/7.0.10
16
Content-Length: 0
17
Content-Type: application/json; charset=UTF-8
18
19
$ curl -i -H "Accept: application/json" "http://localhost:8888/api/items/8"
20
HTTP/1.1 404 Not Found
21
Date: Tue, 25 Oct 2016 23:32:28 GMT
22
Server: Apache/2.2.31 (Unix) mod_wsgi/3.5 Python/2.7.12 PHP/7.0.10 mod_ssl/2.2.31 OpenSSL/1.0.2h DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0
23
X-Powered-By: PHP/7.0.10
24
Content-Length: 115
25
Content-Type: application/json; charset=UTF-8
26
27
{"name":"Not Found","message":"Object not found: 8","code":0,"status":404,"type":"yii\\web\\NotFoundHttpException"}

Las peticiones para un registro borrado devuelven un error 404.

Peticiones POST

Para mis peticiones post, cambié a la app de Chrome Postman:

Programming With Yii2 Chrome Directory Postman Extension Landing PageProgramming With Yii2 Chrome Directory Postman Extension Landing PageProgramming With Yii2 Chrome Directory Postman Extension Landing Page

Registrarse para Postman fue sencillo:

Programming With Yii2 Postmand Sign UpProgramming With Yii2 Postmand Sign UpProgramming With Yii2 Postmand Sign Up

Y después pude enviar peticiones a mi API localhost en una GUI más amigable:

Programming With Yii2 POST Request Shown in Postman UXProgramming With Yii2 POST Request Shown in Postman UXProgramming With Yii2 POST Request Shown in Postman UX

Después, recuperé los datos vía curl, record 577:

1
$ curl -i -H "Accept: application/json" "http://localhost:8888/api/items/577"
2
HTTP/1.1 200 OK
3
Date: Tue, 25 Oct 2016 23:40:44 GMT
4
Server: Apache/2.2.31 (Unix) mod_wsgi/3.5 Python/2.7.12 PHP/7.0.10 mod_ssl/2.2.31 OpenSSL/1.0.2h DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0
5
X-Powered-By: PHP/7.0.10
6
Content-Length: 219
7
Content-Type: application/json; charset=UTF-8
8
9
{"id":577,"title":"Jeff Reifman","path":"reifman",
10
"detail":"A programmer on earth.","status":0,
11
"posted_by":1,"image_url":"","favorites":0,
12
"stat_1":0,"stat_2":0,"stat_3":0,"created_at":1477436477,
13
"updated_at":1477436477}

Postman resultó esencial para redondear mis pruebas ya que la linea de comando curl no es sencilla de configurar para envíos POST.

Mirando Hacia Adelante

En adición a su resumen de inicio rápido REST, la documentación Yii 2.0 proporciona detalle en un arreglo de otros aspectos de creación de API:

Espero tener la oportunidad de explorar más de estos en futuros episodios. Pero ciertamente, uno de los siguientes pasos es crear una API para Meeting Planner en la serie startup.

En conclusión, construir una API REST básica con el framework MVC Yii es bastante simple. El equipo de Yii ha hecho un gran trabajo estandarizando funcionalidad para un requerimiento muy importante, APIs REST. Espero que hayas disfrutado aprender sobre ellas.

Si tienes cualquier pregunta o sugerencia, por favor publícalas en los comentarios. Si quisieras seguir a la par con mis tutoriales Envato Tuts+ futuros y otras series, por favor visita mi página de instructor o sígueme @reifman. Definitivamente revisa mi serie startup y Meeting Planner.

Enlaces Relacionados

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.