Giancarlos Salas
Giancarlos Salas

Giancarlos Salas

Symfony Async

API hecho con Symfony y llamadas asíncronas

Giancarlos Salas's photo
Giancarlos Salas

Published on Mar 1, 2021

3 min read

En muchos lenguajes de programación como C# y Java, realizar llamadas asíncronas es relativamente más sencillo y se encuentra disponible nativamente con el lenguaje, pero en PHP no existe tal cosa, al menos no nativamente, así que el objetivo será implementar esto en un API con Symfony.

Async Lib

ReactPHP es un conjunto de librerías hechas en PHP que tiene este enfoque asíncrono (existe otra alternativa como amphp), entre los cuales existe el paquete react/promise, donde se manejan promesas muy similar a Javascript.

$promise
  ->then(function ($value) {
     // done
  }, function ($error) {
    // error
  });

Los procesos asíncronos suelen utilizarse en casos como: peticiones http, conexión a base de datos, lectura de archivos, etc; en nuestro ejemplo realizaremos una petición http, reactphp ya cuenta con un HttpClient que se encuentra en el paquete react/http.

Realizaremos peticiones a un Fake API, para propósitos de demostración.

$loop = React\EventLoop\Factory::create();

$client = new React\Http\Browser($loop);

$client->get("https://jsonplaceholder.typicode.com/todos/1")
       ->then(function (ResponseInterface $response) {
           $json = (string)$response->getBody();
           // procesar json
       });

$loop->run();

Symfony Project

Como lo indica el título, utilizaremos Symfony para exponer un API utilizando estas llamadas asíncronas, para inicializar nuestro proyecto debemos ejecutar el siguiente comando:

symfony new symfony-async

Podemos descargar symfony cli desde aquí.

Evidentemente Symfony no tiene soporte integrado para manejar estas devoluciones asíncronas, para lo cual tendremos que utilizar un paquete de DriftPHP, llamado drift/http-kernel, y la configuración es tan simple como reemplazar en el archivo src/Kernel.php la clase base del Kernel.

use Drift\HttpKernel\AsyncKernel as BaseKernel;
//use Symfony\Component\HttpKernel\Kernel as BaseKernel;

Y ahora con esto, ya podríamos cambiar el tipo de respuesta en los métodos de nuestro controlador que requieran devoluciones asíncronas.

class ItemsController
{
    // Modelo async
    public function index(): PromiseInterface
    {
        // ...
        return $promise->then(fn ($data) => new Response($data));
    }

    // Modelo por defecto
    public function hello(): Response
    {
        return new Response('hello');
    }
}

Ejecutar

Después de tener nuestra aplicación lista para ejecutarse, necesitamos un tipo de webserver especial, el cual se encuentra en el paquete drift/server, pero como esto esta hecho específicamente para proyectos drift, necesitamos agregar un adaptador para que funcione en nuestro ejemplo, esto podemos encontrarlo aquí .

Ahora estamos listo para ejecutar nuestra aplicación:

vendor/bin/server run 0.0.0.0:8000 --adapter=App\\AppKernelAdapter

📝Puedes encontrar el código completo en el siguiente repositorio.

 
Share this