Trabajando con Azure Functions y TypeScript

Azure Functions es una solución de Microsoft para el procesamiento de datos, APIS y microservicios de computación sin servidor. Posee una serie de ventajas y características a tener en cuenta:

  • Ofrece una escalabilidad flexible basado en el volumen de trabajo.
  • Cuenta con un modelo de programación integrado basado en desencadenadores y enlaces que permiten conectarse a diferentes eventos.
  • Un repertorio de herramientas DevOps integradas, además de una experiencia de programación End-to-End que conduce desde el desarrollo y compilación hasta la depuración e integración continua además de la entrega continua (CI/CD).

Se basa en una arquitectura Serverless basada en microservicios (“Funciones como servicio”), por lo que recomendable es dividir las funciones, que se regularán en función de la demanda. Por lo que es auto-escalado, pagamos por servicio y no nos obliga a gestionar la infraestructura.

Requisitos

Para hacer una demostración de cómo funciona Azure Functions con TypeScript y familiarizarnos con el entorno, vamos a necesitar las siguientes herramientas:

Posteriormente, debemos tener instalada la versión correspondiente de Azure Functions Core Tools que nos permitirá trabajar en local, conectarnos en nuestra cuenta de Azure y, además, desplegar nuestros function projects.

Para ello, en MacOS utilizaremos el siguiente comando:

brew tap azure/functions
brew install azure-functions-core-tools@3

Creando un Functions project en local

El procedimiento para crear nuestro proyecto en local es bastante intuitivo, solo tendremos que ejecutar el siguiente comando:

func init MyFunctionDemo

Y seleccionar qué tipo de proyecto queremos crear, el asistente nos ofrecerá las siguientes opciones:

Select a worker runtime:
1. dotnet
2. node
3. python
4. powershell
Choose option: 2
node
Select a Language:
1. javascript
2. typescript
Choose option: 2
typescript

Ello te generará un archivo package.json y tsconfig.json que te ayudarán a transcompilar todo el proyecto a JavaScript. Para comprobar que todo ha sido instalado correctamente debemos ejecutar el siguiente comando el el directorio donde tengamos el proyecto:

func start

Donde podremos comprobar que el servicio está corriendo en la dirección: http://0.0.0.0:7071

Para crear nuestro primer ejemplo usaremos el comando:

func new

Se seleccionamos la octava opción: 8. HTTP trigger, nos generará un archivo index.ts con el siguiente código:

import { AzureFunction, Context, HttpRequest } from "@azure/functions"

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    context.log('HTTP trigger function processed a request.');
    const name = (req.query.name || (req.body && req.body.name));

    if (name) {
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

export default httpTrigger;

Si ejecutamos mediante consola los siguientes comandos:

npm install
npm start 

Debería darnos el siguiente output:

Found the following functions:
Host.Functions.MyHttpTrigger

Job host started
Http Function MyHttpTrigger: http://localhost:7071/api/MyHttpTrigger

De esta forma, podremos comprobar que la aplicación está perfectamente desplegada haciendo una petición a:

curl --get http://localhost:7071/api/MyHttpTrigger?name=Azure%20Mola

Desplegar la aplicación en Azure

Por último, para desplegar nuestra aplicación en Azure, debemos utilizar el siguiente comando:

func azure functionapp publish <FunctionAppName>

Este comando desplegará automáticamente tu Function en tu cuenta. Incluso podríamos configurar el entorno para desplegar nuestra aplicación en un entorno de staging o usar Circle-CI y JEST comprobar que todo está correcto antes de hacer push al branch de producción.

Hasta aquí esta primera toma de contacto con TypeScript y Azure, sin duda habrá más posts similares en un futuro.

Happy coding!

Novedades en TypeScript 3.7

La versión 3.7 de TypeScript viene repleta de novedades. Lo primero que debes saber, como siempre, es que si quieres usar esta versión puedes hacerlo a través del comando:

npm install -g typescript@latest

Esta versión se caracteriza por añadir características de ECMAScript para tratar valores null y undefined. Sin más, comencemos a resumir de forma muy breve las novedades más importantes que presentará esta nueva versión.

Optional Chaining

El encadenamiento opcional nos permite leer cada una de las propiedades dentro de una cadena de objetos sin tener que incluir condiciones que validen que cada una de sus referencias son correctas. Viene representado por el operador ?

Si tenemos en cuenta el siguiente fragmento de código, extraído del blog oficial de TypeScript, podemos ver exactamente cómo funciona esta nueva característica:

let x = foo?.bar.baz();

En esta situación, si foo está definido la operación se llevará a cabo, pero si es null o undefined el programa se interrumpirá.

Como se indica en el código escrito previamente, usando el encadenamiento opcional sería como escribir esto:

let x = (foo === null || foo === undefined) ?
    undefined :
    foo.bar.baz();

Nullish Coalescing

Se trata de otra característica de ECMAScript que viene de la mano junto con la explicada con anterioridad. Sigue en la misma línea de gestionar valores cuando estos sean null o undefined. Podemos usarlo con el operador ??. Veámoslo con un sencillo ejemplo:

let x = foo ?? bar();

En este caso, vamos a usar el valor de foo cuando tengamos asignado un valor, pero cuando sea null o undefined vamos a realizar la operación bar() en su lugar. Esto nos permitirá tener siempre tener un valor u opción por defecto ante este tipo de situaciones.

Assertion functions

Conocido por estar ya introducido en otros lenguajes, se trata de una expresión cuya premisa va a ser siempre true y que, en caso contrario, lanzará una excepción:

function yell(str) {
    assert(typeof str === "string");

    return str.toUppercase();
    //         ~~~~~~~~~~~
    // error: Property 'toUppercase' does not exist on type 'string'.
    //        Did you mean 'toUpperCase'?
}

function assert(condition: any, msg?: string): asserts condition {
    if (!condition) {
        throw new AssertionError(msg)
    }
}

Estas serían las tres grandes novedades que presenta esta versión de TypeScript, no obstante, para obtener información más detallada, como he citado anteriormente, podéis consultar directamente el post oficial del anuncio donde se incluyen todas sus nuevas características entre las que se encuentra la posibilidad de usar –declaration and –allowJs conjuntamente (lo que facilitará la migración de tu proyecto a TypeScript) o el uso de Recursive Type Aliases, aunque en un futuro analizaremos más detalladamente alguna de ellas.

Happy coding!

TypeScript + VueJs

En el último meetup de Sevilla TypeScript se ha hablado de las ventajas de utilizar TypeScript con Vue.js, además de cómo iniciar un proyecto haciendo énfasis en las diferencias que existen respecto a otras tecnologías. En este post, vamos a ahondar un poco en este asunto, tratando de mostrar cuáles son las ventajas y desventajas de utilizar Vue.js con TypeScipt.

¿Qué es Vue?

Vue.js es un framework progresivo para construir interfaces de usuario bastante versátil, es Open Source y cuenta más de 140.000 estrellas en GitHub. Fue desarrollado por Evan You con la idea de obtener lo mejor de otras tecnologías como Angular o React, quedándose solo con lo imprescindible, haciendo así una tecnología bastante ligera (el Core de VueJS tan solo ocupa unos 20KB).

Características:

  • Es reactivo.
  • Es progresivo, como hemos mencionado anteriormente, podemos decidir qué partes de la tecnología incluimos en nuestro proyecto. Está diseñado para ser adoptado incrementalmente.
  • Al igual que React, el uso del DOM virtual hace que sea sensación de renderizado sea bastante fluida.

Integración con TypeScript

Aunque la integración es cada vez mejor (sobre todo desde a partir de la versión 3.x), quizás habría que ser prudente a la hora de llevar código con ambas tecnologías a producción. Otro aspecto que destacar es que hasta ahora la documentación que puedes encontrar sobre ambas tecnologías es escasa aunque, sin duda, si tuviera que empezar un proyecto a día de hoy con Vue lo haría con TypeScript.

La configuración necesaria para iniciar un proyecto, tal y como se recomienda en la web oficial, es la siguiente:

// tsconfig.json
{
  "compilerOptions": {
    // this aligns with Vue's browser support
    "target": "es5",
    // this enables stricter inference for data properties on `this`
    "strict": true,
    // if using webpack 2+ or rollup, to leverage tree shaking:
    "module": "es2015",
    "moduleResolution": "node"
  }
}

Por otro lado, para crear nuestro primer proyecto será necesario solo introducir en consola lo siguiente:

# 1. Install Vue CLI, if it's not already installed
npm install --global @vue/cli

# 2. Create a new project, then choose the "Manually select features" option
vue create my-project-name

Si quieres practicar con código, te recomiendo que uses este repositorio de iniciación.

¿Qué lo diferencia de React?

Lo primero que debemos mencionar es que, en términos de popularidad, actualmente React gana la partida. Esto significa que tendrás más documentación o ejemplos al respecto que te ayudarán a solucionar problemas más rápidamente ya tiene detrás a Facebook respaldando la tecnología además de una gran comunidad, aunque la popularidad de Vue está en constante crecimiento. Por otro lado, en cuanto a tecnología móvil, la que ofrece React es más madura, es decir, si quieres montar un proyecto tanto para web como para mobile la recomendación es React. Otra diferencia significativa es que, aunque ambas tecnologías tienen una arquitectura basada en componentes, en Vue se usa HTML para las plantillas (aunque también puedes usar otros estilos como JSX) en un único documento mientras que en React se utiliza JavaScript.

Conclusiones

Como hemos visto Vue propone una gran solución con la premisa de que a veces, menos, es más. Vue es una gran herramienta, que te abre grandes posibilidades con muy poco, sobre todo si posees menos experiencia en el desarrollo en la parte del frontend. Por todo lo citado con anterioridad, diría que Vue se ajusta a tus necesidades si tienes un proyecto de pequeña o mediana escala, mientras que React estaría recomendado para grandes proyectos. Este post ha sido bastante introductorio, sin embargo, más adelante habrá una segunda parte con otro ejemplo más avanzado.

Happy coding!

TypeScript + React

En el segundo meetup de Sevilla TypeScript realicé una ponencia introductoria sobre las ventajas de usar React con TypeScript. Con este post pretendo hacer una extensión de la introducción que hice en aquella ocasión. Para ello, vamos a aprender cómo iniciar nuestro primer proyecto con TypeScript y React.

¿Qué es React?

Es una librería escrita en JavaScript, una de las más populares, pues cuenta con más de 100.000 stars en GitHub. Está creado y matenido por Facebook, pensado para construir interfaces (UI) en la capa de front-end. Determina como los datos son almacenados mediante props y state. Las props (propiedades) son los atributos que se pueden definir en un componente, mientras que el state se definiría como la representación de dicho componente en un determinado momento, que irá mutando en función de su ciclo de vida.

¿Cuáles son sus ventajas?

Es declarativo, es decir, como hemos comentado previamente contamos con el estado de una aplicación y sus componentes responden a ese estado, esta circunstancia hace que el código sea mucho más predictivo y fácil de debbugear. Otra de sus ventajas se muestra en el rendimiento, ya que antes se realizan las operaciones sobre el DOM virtual, eso provoca que la sensación de renderizado sea mucho más fluida.

¿Cómo creamos nuestra primera aplicación?

Desde octubre del año pasado, esta tarea es bastante sencilla, gracias a que create-react-app cuenta con soporte oficial para TypeScript. Como puedes intuir leyendo su nombre, esta app nos permitirá crear una aplicación básica en react con el propósito de aprender cómo funciona en un entorno de desarrollo cómodo o crear componentes nuevos que luego podremos usar en nuestros proyectos.

Para crea nuestra nueva app, solo tendremos que tener instalado una versión de Node >= 6 y usar el comando:

npx create-react-app my-app --typescript

Sí, así de sencillo. Esto nos generará un proyecto con la siguiente estructura:

my-app
├── README.md
├── node_modules
├── package.json
├── tsconfig.json (opciones de compilación en TS)
├── .gitignore
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
└── src
    ├── App.css
    ├── App.js
    ├── App.test.js
    ├── index.css
    ├── index.js
    ├── logo.svg
    └── serviceWorker.js

Y, además, nos generará un archivo tsconfig.json, donde pondremos todas las instrucciones que el compilador deberá obedecer.

Una vez con el proyecto creado, veamos cuáles son las ventajas de usar TypeScript con react con un sencillo ejemplo. La más importante, sin duda, el tipado. Es decir, podremos declarar componentes e intuir más fácilmente cuál será su funcionamiento dependiendo del tipo de parámetro que recibe. Veámoslo con un sencillísimo ejemplo, vamos a crear un nuevo componente que recibirá un número que será, en este caso, nuestra edad:

 function DiMiEdad({edad}: {edad: number}){
      return <div>Hola! Tengo: {edad} años</div>
    }

Cuando tratemos de invocarlo, en cuanto escribamos la primera letra, el editor nos sugerirá la función que vamos a usar, indicándonos qué tipo parámetro acepta, para no llevarnos a confusiones:

la magia ocurre

Esta la clave de todo, lo que hará que nos evitemos un quebradero de cabeza, lo que le da toda la potencia necesaria a nuestro proyecto para hacer que, cuando otras personas o incluso nosotros mismos trabajemos en ello, todo sea mucho más fácil. El ejemplo es bastante sencillo, pero se intuye que las posibilidades, en este sentido, son muchísimas para hacer que todo sea más robusto y fácilmente escalable.

Por otro lado, si tratamos de asignarle a edad un valor de tipo string, el compilador intervendrá y no hará su cometido:

Failed to compile.

/Users/christianivanov/Documents/ejemplo react2/my-app/src/App.tsx
TypeScript error: Type 'string' is not assignable to type 'number'.  TS2322

    11 |           <p>
    12 |             Edit <code>src/App.tsx</code> and save to reload.
  > 13 |             <DiMiEdad edad = {'nombre'}/>
       |                       ^
    14 |           </p>
    15 |           <a
    16 |             className="App-link"

Todo esto nos ayudará a prevenir errores no deseados. Grandes empresas como AirBnb han sido capaces de reducir sus errores en producción usando TypeScript un 38%, una cifra bastante significativa, que nos deja evidencias significativas de las ventajas de usar TypeScript con otras tecnologías para minimizar errores.

¡Esto es todo por ahora! Solo quería mostrar mediante un pequeño ejemplo las posibilidades de juntar TypeScript con React. En futuros posts, seguiremos aprendiendo como combinar ambas tecnologías.

Happy coding!

Analizando el compilador de TypeScript

Siempre me ha apasionado la programación a bajo nivel. Si quieres saber cómo funciona un lenguaje, estudia su compilador. Es por ello que la curiosidad me ha conducido a analizar el compilador de TypeScript, donde he encontrado algunas cosas interesantes. En primer lugar, veamos en un diagrama la estructura del compilador de TypeScript, para un posterior análisis:

Arquitectura del compilador

Como podemos intuir, el Core es la parte más importante. Cuenta con el Type Resolver (checker.ts) que valida cada operación semántica y genera el diagnóstico adecuado en caso de error. También podemos ver el Emitter, encargado de convertir el input (archivos .ts and .d.ts) en archivos JavaScript o el Language Service, que soporta las operaciones de edición como autocompletado de sintaxis, re-factoring o el soporte incremental de compilación. Por otro lado, el Standalone Compiler se encarga de la integración con otros motores, por ejemplo, con Nodejs. La siguiente capa con VSShim y tsserver tiene la función de integrarse con Visual Studio y otros editores de texto para hacer que la experiencia sea mucho más sencilla. Por último, nos encontramos con el editor, donde daremos todas las instrucciones necesarias para que el Core haga que la magia suceda.

Estructura de datos: Abstract Syntax Tree (AST)

En cuanto a la estructura de datos, nos encontramos con el Abstract Syntax Tree que es el encargado de clasificar, mediante nodos, cada elemento generado por nuestro código. Con el SourceFile se va referenciando cada uno de los identificadores mencionados. Por tanto, un programa (unidad de compilación) está compuesto por un conjunto de SourceFile. Otra pieza destacada es el Symbol, que conecta cada uno de los nodos con los que estén relacionados dentro de la misma entidad. Se define de la siguiente forma:

  function Symbol(this: Symbol, flags: SymbolFlags, name: __String) {
       this.flags = flags;
       this.escapedName = name;
       this.declarations = undefined;
       this.valueDeclaration = undefined;
       this.id = undefined;
       this.mergeId = undefined;
       this.parent = undefined;
}

Son creados por el Binder, cuya principal función es recopilar varias piezas de código para otorgarle coherencia o cohesión. Citando un ejemplo del libro de Remo Jansen Learning TypeScript, el lenguaje tiene una característica denomina ‘declaration merging’ que permite precisamente hacer esta fusión, veámoslo un ejemplo con código:

 interface Person {
       name: string;
}

interface Person {
       surname: string;
}

const person: Person = { name: "Christian", surname: "Ivanov" };

En este caso, el comportamiento esperado del Binder es unificar las propiedades del tipo declarado previamente y mergearlo.

Repasando el proceso de compilación

Todo el proceso comienza con el procesamiento de todos los archivos ubicados en /// <reference path=… /> e import. Como hemos mencionado con anterioridad, el parser crea los nodos, que no es más que una representación abstracta del input que ha procesado en formato de árbol. Una vez hecho, se generan los Symbols. Cada Symbol es creado para identificar cada uno de los elementos procesados, pudiendo tener el mismo nombre, pero diferente alcance. Al ser generados, se crea un SourceFile mediante el uso de la API createSourceFile. Por lo que un programa es, básicamente, un conjunto de SourceFiles junto con una configuración de compilación (CompilerOptions). Cuando el programa se ha instanciado, entra en acción el TypeChecker, que es el core del compilador. Entre sus funciones, se encuentra: recopilar todos los símbolos creados en los diferentes SourceFiles, mergearlo en una unidad y determinar su tipo, para localizar errores. Estando todo validado, el Emitter genera el output, archivos de tipo .js, .jsx, .d.ts, y .js.map (recuerda que el compilador de TypeScript, transcompila todo a JavaScript).

Sin más, el propósito de este post solo era echar un pequeño vistazo a la capa más superficial del compilador, si quieres ver cómo sería el resultado del AST que hemos mencionado, podéis echarle un vistazo al siguiente enlace. Por otro lado, para interactuar con la API que el mismo compilador proporciona, podéis también echarle un ojo a ts-morph, un proyecto que nos permitirá leer y manipular el AST.

Happy coding!