<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matias Navarro Carter</title>
    <description>The latest articles on DEV Community by Matias Navarro Carter (@mnavarrocarter).</description>
    <link>https://dev.to/mnavarrocarter</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F159409%2F86d0c515-9455-4e8b-aa6c-4896d8ff3b8a.jpeg</url>
      <title>DEV Community: Matias Navarro Carter</title>
      <link>https://dev.to/mnavarrocarter</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mnavarrocarter"/>
    <language>en</language>
    <item>
      <title>Introducing Espresso</title>
      <dc:creator>Matias Navarro Carter</dc:creator>
      <pubDate>Mon, 20 May 2019 21:44:53 +0000</pubDate>
      <link>https://dev.to/mnavarrocarter/introducing-espresso-4p14</link>
      <guid>https://dev.to/mnavarrocarter/introducing-espresso-4p14</guid>
      <description>&lt;p&gt;Cuando comencé a utilizar Node me enamoré de muchas cosas. Una de las primeras cosas fue el sistema de módulos: una forma bastante inteligente de exportar estado y comportamiento, manteniendo encapsulamiento y sin preocuparnos por tener un DI Container. Sin embargo, una de las cosas que más me gustó también es lo flexible y potente que es Express.js, la capa HTTP por antonomasia de Node.&lt;/p&gt;

&lt;p&gt;Me gustó tanto que tenía muchas ganas de usarlo en PHP. Si bien es cierto, PHP cuenta con algunos microframeworks similares como Expressive y Slim, aún había algunas cosas que no me agradaban del todo en ellos.&lt;/p&gt;

&lt;p&gt;Por ello, me decidí a crear Espresso, un clon de Express.js para PHP. Actualmente se encuentra en versión &lt;code&gt;1.0.0-alpha1&lt;/code&gt;. Esto significa que la api ya está bien definida y funciona, pero lo que faltan son extensivas pruebas unitarias antes de sentirme confiado de liberarlo con un tag productivo.&lt;/p&gt;

&lt;p&gt;La idea de este artículo es doble. La primera, es dar a conocer el proyecto y buscar personas que quieran contribuir al mismo por medio de probarlo, jugar con él, buscar bugs y ofrecer pull requests. La segunda, es mostrar a potenciales usuarios cómo se usa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creando la Instancia de Espresso
&lt;/h2&gt;

&lt;p&gt;Espresso es interoperable. En el mundo PHP, esto quiere decir que sigue los estándares HTTP definidos por PHP-FIG. Por ello, para usarlo, el requerimiento mínimo es que cuentes con una implementación de PSR-7 y una función que emita una Respuesta PSR-7.&lt;/p&gt;

&lt;p&gt;Personalmente recomiendo instalar el fabuloso &lt;code&gt;zendframework/zend-diactoros&lt;/code&gt; y &lt;code&gt;http-interop/response-sender&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Entonces, para instalar Espresso y estas dos sugerencias, copia este comando en la carpeta de tu proyecto y podrás empezar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require espresso/app dev-master zendframework/zend-diactoros http-interop/response-sender
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;NOTA: Espresso en &lt;code&gt;dev-master&lt;/code&gt; sólo es necesario en la fase alpha.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para crear una instancia de Espresso es tan simple como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// No te olvides de requerir el autoload de composer antes!&lt;/span&gt;
&lt;span class="nv"&gt;$app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Espresso&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;\Zend\Diactoros\ServerRequestFactory&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'fromGlobals'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s1"&gt;'\Http\Response\send'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Estos dos parámetros le permiten a Espresso poder llamar a su método &lt;code&gt;run&lt;/code&gt;. Lo que este método hace, es crear la instancia de &lt;code&gt;ServerRequestInterface&lt;/code&gt; usando el callable, obtener una instancia de &lt;code&gt;ResponseInterface&lt;/code&gt; del pipeline de middleware, y luego emitir esa respuesta usando el callable provisto.&lt;/p&gt;

&lt;p&gt;Una vez creada la instancia de Espresso, es muy fácil inyectar middleware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;LoggingMiddleware&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Registrando rutas en Espresso
&lt;/h2&gt;

&lt;p&gt;Para registrar una ruta en Espresso, tienes a tu disposición seis métodos, que son bastante clásicos: &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;post&lt;/code&gt;, &lt;code&gt;put&lt;/code&gt;, &lt;code&gt;patch&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt; y &lt;code&gt;any&lt;/code&gt;. Cada uno de estos métodos toma el &lt;em&gt;path&lt;/em&gt; de la ruta y un número indefinido de instancias de &lt;code&gt;MiddlewareInterface&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Este handler sirve la página de inicio&lt;/span&gt;
&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;HomePageHandler&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// Este handler sirve el panel de administración, pero primero se&lt;/span&gt;
&lt;span class="c1"&gt;// asegura que el usuario esté autenticado.&lt;/span&gt;
&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BasicAuthMiddleware&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AdminPanelHandler&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Por supuesto, puedes pasar &lt;em&gt;placeholders&lt;/em&gt; a las rutas que definas. Éstos serán inyectados en los atributos de &lt;code&gt;ServerRequestInterface&lt;/code&gt; bajo el nombre dado al placeholder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/users/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$req&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Esto devuelve el valor de id.&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Nota que además se pueden pasar callables o instancias de &lt;code&gt;RequestHandlerMiddleware&lt;/code&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A diferencia de otros micro-frameworks en PHP, Espresso no cuenta con el tradicional sistema de enrutamiento consistente en un &lt;em&gt;Route Collector&lt;/em&gt; y un &lt;em&gt;Dispatcher&lt;/em&gt;. En vez de eso, cada ruta es un middleware en sí mismo, y recibe una instancia de &lt;code&gt;ServerRequestInterface&lt;/code&gt; desde la cual obtiene información para ver si hay un match.&lt;/p&gt;

&lt;p&gt;Esto podría parecer ineficiente, y lo sería si definimos cada ruta de nuestra aplicación directamente en la instancia de Espresso. Sin embargo, Espresso cuenta con otro concepto tomado desde Express.js: la habilidad de incrustar un componente enrutable bajo un &lt;em&gt;path&lt;/em&gt;. Por ejemplo, pensemos en un módulo de usuarios:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$userModule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;RoutableHttpComponent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Definimos algunas rutas relativas a este módulo&lt;/span&gt;
&lt;span class="nv"&gt;$userModule&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Devolver una lista de usuarios aquí&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nv"&gt;$userModule&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Crear un usuario aquí&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nv"&gt;$userModule&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Devolver un usuario específico aquí&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Y luego las importamos en la aplicación bajo un path en común&lt;/span&gt;
&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/users'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$userModule&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;En realidad, Espresso no es más que una extensión de este &lt;code&gt;RoutableHttpComponent&lt;/code&gt; que posee el método &lt;code&gt;run&lt;/code&gt;, y algunos métodos de configuración. Podrías hacer tu propia aplicación usando sólo el &lt;code&gt;RoutableHttpComponent&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Espresso e Inyección de Dependencias
&lt;/h2&gt;

&lt;p&gt;Si usas un contenedor de inyección de dependencias que implementa la interfaz definida por PSR-11, entonces puedes hacer que Espresso lo use para resolver cualquier depdendencia pasada a los métodos antes mencionados.&lt;/p&gt;

&lt;p&gt;Esto puede hacerse usando el método &lt;code&gt;setContainer&lt;/code&gt; de Espresso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;setContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$aContainerInstance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Luego, podrás ser capaz de definir rutas e inyectar middleware sólamente referenciando el nombre del servicio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'app.homepage_handler'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Internamente, Espresso resolverá este servicio y lo instanciará de manera &lt;em&gt;Lazy&lt;/em&gt; por defecto.&lt;/p&gt;

&lt;p&gt;Cada componente puede recibir una instancia del container también.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$module&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;RoutableHttpComponent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$module&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;setContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$aContainerInstance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Otras utilidades
&lt;/h2&gt;

&lt;p&gt;La instancia de Espresso cuenta con unas cuantas utilidades comunes para hacer tu vida más simple. Estoy pensando en añadir muchas otras más y sería genial poder tener feedback al respecto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sesión
&lt;/h3&gt;

&lt;p&gt;La primera utilidad es la habilidad de identificar únicamente un cliente a través de cookies que conforman una sesión. Podemos hacer esto llamando al método &lt;code&gt;$app-&amp;gt;session();&lt;/code&gt;. Este método toma tres argumentos y sólo el primero es obligatorio:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Un &lt;em&gt;secret key&lt;/em&gt; de 32 bits. Puede ser generado en la terminal con: &lt;code&gt;php -r "echo bin2hex(random_bytes(16));"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Un nombre para la cookie de sesión. Por defecto es &lt;code&gt;_espresso&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;El tiempo de expiración de la sesión como string de &lt;code&gt;DateTime&lt;/code&gt;. Por defecto es &lt;code&gt;+1week&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Es importante notar que el manejo de sesión en Espresso no usa el handler nativo de PHP, sino que encripta un string &lt;code&gt;json&lt;/code&gt; que guarda los datos de sesión en una cookie del lado del cliente. Cualquier modificación es inmediatamente detectada, lo que rehace la sesión e invalida cualquier autenticación previa. Si la sesión es modificada, la cookie vuelve a setearse. &lt;/p&gt;

&lt;p&gt;La ventaja de este método es su simplicidad, efectividad, seguridad y escalabilidad. La desventaja es que no puedes colocar demasiados datos en la sesión, debido a que las cookies poseen capacidad bastante limitada.&lt;/p&gt;

&lt;h3&gt;
  
  
  Body Parsers
&lt;/h3&gt;

&lt;p&gt;Si estás construyendo una Api REST o procesando input de formularios, Espresso provee un método para configurar rápidamente el &lt;em&gt;parsing&lt;/em&gt; del cuerpo de una &lt;em&gt;request&lt;/em&gt;. Tan solo llamando el método &lt;code&gt;$app-&amp;gt;parseBody()&lt;/code&gt; y pasandole un string, ya sea &lt;code&gt;json&lt;/code&gt; o &lt;code&gt;form&lt;/code&gt; (o ambos), automáticamente tendrás tu input disponible como un arreglo en el método &lt;code&gt;ServerRequestInterface::getParsedBody()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;parseBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'json'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  "¡Tú puedes contribuir!"
&lt;/h2&gt;

&lt;p&gt;Hay unas cuantas cosas más que me gustaría añadir a Espresso, ¡y estoy muy ansioso de escuchar ideas! Si tienes algún feature que quieras proponer, puedes abrir un &lt;em&gt;issue&lt;/em&gt; en el &lt;a href="https://github.com/espresso-php/app"&gt;repositorio de Github&lt;/a&gt; o puedes instalar el &lt;a href="https://packagist.org/packages/espresso/app"&gt;paquete de composer&lt;/a&gt; y jugar un poco con el framework.&lt;/p&gt;

&lt;p&gt;Mientras tú haces eso, yo estaré escribiendo pruebas unitarias y añadiendo algunos features extra. Una vez obtenido un 90% de coverage (que probablemente será en menos de dos semanas) lanzaré la versión &lt;code&gt;1.0.0-rc1&lt;/code&gt;. A mediados de Junio espero poder hacer el lanzamiento de &lt;code&gt;1.0.0&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>php</category>
      <category>framework</category>
      <category>http</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
