Aplicaciones web con Zero Server

Zero Server es un nuevo framework de desarrollo web basado en JavaScript muy interesante, es totalmente sin configuración y soporta muchas tecnologías, Zero se encarga de configurar rutas, construir y transpilar la aplicación y te deja escribir código de Node.js (con Express), React, HTML, Markdown, MDX o simples archivos estáticos, todo en una carpeta

Instalación

Como cualquier librerías o framework JavaScript se puede instalar con npm

npm install zero

O con yarn

yarn add zero

Hola Mundo en Zero

El Hola Mundo de Zero es crear un API que devuelva la hora y un Frontend que pida esa hora al API y la muestre.

Lo primero es el API, en el proyecto se crea una carpeta /api con el archivo time.js, la carpeta /api no es obligatoria y time.js podría estar en la raíz del proyecto, por organización es mejor ponerlo en /api.

Dentro de time.js se va a exportar una función que recibe Request y Response de Express.js

const format = require("date-fns/format");

function main(req, res) {
  const time = format(Date.now(), "hh:mm A");
  res.send({ time: time });
}

module.exports = main;

Una vez guardado se corre zero en el proyecto, Zero se va a encargar de instalar cualquier dependencia del código e iniciar el servidor.

Si ahora se accede a http://localhost:3000/api/time Zero va a responder con un JSON similar a este

{ "time": "11:14 PM" }

¡Con esto está listo el primer endpoint del API!

Sin apagar el servidor. Podemos crear ahora una aplicación de React que consuma esta API, para eso se crear un archivo index.jsx en la raíz, Zero identifica archivos .jsx como componentes de React.

Dentro de index.jsx se coloca el siguiente código.

import React, { Component } from "react";

class Home extends Component {
  static async getInitialProps() {
    const response = await fetch("/api/time");
    const data = await response.json();
    return { time: data.time };
  }

  render() {
    return <h1>Current time is: {this.props.time}</h1>;
  }
}

export default Home;

Un componente normal de React que usa clases, con un método estático adicional llamado getInitialProps (inspirado en Next.js), este método asíncrono permite al componente obtener información inicial antes de renderizarse, tanto en el servidor como en el cliente, y recibir esa información como props.

Si se accede a https://localhost:3000 Zero va a empaquetar la aplicación de React y hacer render, al entrar se va a ver una página con el siguiente mensaje.

Current time is: 11:20 PM

Con eso esta lista la aplicación, algo super simple pero sin configurar nada.

Archivos estáticos

Estos son archivos de imágenes, vídeos, documentos, etc. y pueden estar ubicados junto al código de la app en cualquier lugar del proyecto. Zero los sirve tal cual sin efectuar ninguna modificación.

Node

Como ya se vió arriba Zero trata archivos .js como código de Node.js y los sirve como URLs con su nombre de archivo como endpoint. Cada archivo debe exportar una sola función que es usada para manejar peticiones.

TypeScript

Zero soporta también TypeScript, si un archivo termina en .ts Zero los pasa de TypeScript a JavaScript y lo usa como un archivo normal de JavaScript.

Query

Zero lee los parámetros de la query e inyecta una propiedad query al objeto Request.

Verbos http

Zero soporta todos los verbos HTTP. Peticiones POST tiene la información procesada como JSON e inyectada en el objeto Request como body, ya sea json o urlencoded.

Rutas personalizadas

Zero usa los nombres de archivo para las rutas y no tiene forma de configurar rutas propias. En caso de desear convertir algo como /user?id=sergio a /user/sergio Zero envia peticiones de rutas no encontradas a la ruta más cercana, esto quiere decir que si /user/sergio.js no existe pero /user.js existe entonces Zero va a enviar a /user.js una petición en cuyo Request va a existir params como un array con los valores extras, en el ejemplos sería ["sergio"]

Fetch API

Fetch es un API de los navegadores para hacer peticiones HTTP usando promesas. Zero agrega esto también a Node.js y permite hasta hacer peticiones a URls relativas (como /user/sergio).

Si se desea usar fetch desde una URL protegida por autenticación solo hay que pasar credentials: "include" en las opciones de fetch (segundo argumento) y este se encarga de pasar la sesión del usuario al endpoint pedido.

Sesiones

Zero maneja sesiones de usuarios automáticamente. Por defecto Zero guarda las sesiones en una carpeta tmp, esto funciona bien en local pero en producción no es buena idea, para esto Zero soporta Redis y MongoDB

Usando Redis

Zero lee las credenciales desde la variable de entorno SESSION_REDIS_URL, también soporta archivos .env sin configurar nada. Como alternativa se puede agregar SESSION_REDIS_HOST, SESSION_REDIS_PASSWORD y SESSION_REDIS_PORT a las variables de entorno y Zero las combina para conectarse a Redis.

Usando MongoDB

Para usar MongoDB es similar, Zero usa la variable de entorno SESSION_MONGODB_URL, con solo agregarla Zero va a empezar a usar MongoDB para guardar la sesión del usuario.

Tiempo de vida de una sesión

Para configurar el tiempo de vida de una sesión se usa la variable de entorno SESSION_TTL con un valor en segundos. Por defecto el valor es de un año.

React

Como ya se vió arriba Zero soporta React, si se crea un archivo .jsx Zero lo considera una página que usa React y se encarga de hacer el bundle y responder peticiones haciendo Server Side Render de esa página, osea del componente.

Zero además soporta importar archivos CSS, SCSS y SASS e inyecta la sesión del usuario en this.props.

getInitialProps

Zero, al igual que Next.js, soporta el método estático asíncrono getInitialProps. Este método que recibe el objeto Request como req, la sesión del usuario como user y la URL actual como url, todo en un solo objeto. La respuesta de este método es inyectada como prop al componente al momento de hacer render.

Fetch API

Zero soporte usar Fetch en el servidor en getInitialProps, además soporte pasar credenciales de usuario usando credentials: "include" como en Node.js, esto funciona igual tanto en el servidor como en el navegador.

Agregando contenido a <head>

Para agregar contenido al <head> de la página, por ejemplo el <title>, Zero soporta React Helmet, solo hay que importarlo como

import { Helmet } from "react-helmet";

Y usarlo en el render de un componente para agregar contenido al <head>.

TypeScript

También soporta TypeScript en React usando .tsx, similar a como lo soporta en Node.js

HTML

Zero lee el HTML y se encarga de juntar los CSS, SCSS, SASS, JavaScript e incluso imágenes y procesarlas para optimizarlas y cambiar las URLs a los nuevos archivo, todo esto lo hace con Parcel.

Para detectar HTML usa .htm o .html.

Markdown

Zero lee archivos Markdown y los transforma en HTML al usarlos. También soporta MDX lo que permite importas otro archivo Markdown o MDX, importar componentes de React y usarlos directamente en el Markdown.

Incluso importar React Helmet para agregar contenido al <head>.

Palabras finales

Zero Server, aunque nuevo, es un framework muy prometedor ya que permite crear aplicaciones web que combinen varias tecnologías sin configurar nada y optimizadas para producción. Se viene soporte a más tecnologías como .vue para Vue.js o Svelte o soporte a una Progressive Web App.