Una sinfonía en C#

Un pequeño aporte a la comunidad de habla hispana.

Serverless computing: Azure functions.

Una técnica muy común en el desarrollo de software consiste en desacoplar, es decir, intentar independizar una porción de código de otra cosa, ya sea otra porción de código, un dispositivo, un servicios y todo lo que no se pueda, por diferentes motivos, hoy en día esto se intensifica ya que necesitamos cada vez más tener código funcionando lo más rápido posible.

Los servidores, las máquinas virtuales, la nube, los contenedores

En principio, la forma más común de desplegar una aplicación es utilizar un servidor físico, o sea una PC de carne y hueso con un servidor, bases de datos y cosas dentro, esto fue cambiando con el tiempo y nos quisimos independizar de administrar el hardware (si tenemos una PC que administramos nosotros y se corta la energía eléctrica o se rompe un disco tenemos que solucionarlo nosotros) entonces nos movimos a servidores de terceros.

Por otro lado las máquinas virtuales vinieron a ayudarnos un poco con esto, porque hace un poco más simple aislarnos del hardware sin movernos a un servicio de terceros, sin embargo nos seguimos encargando de administrar el sistema operativo nosotros, mantenerlo actualizado y demás.

La nube nos permite poner nuestras máquinas virtuales, copiarlas y demás fácilmente, mejorando bastante el escenario de hacerlo nosotros incluso se pueden mantener actualizadas y cambiar de tamaño fácilmente, pero seguimos atados a tener que instalar todo el software necesario para nuestra aplicación, IIS, Apache, MySQL o lo que sea, y siguen siendo pesadas por así decirlo, además no es raro que instalemos más de una aplicación por máquina lo cual en algún momento nos puede traer problemas.

Por otro lado están los contenedores, que sería como tener solamente la parte que necesitamos de la máquina virtual necesaria para correr nuestra aplicación, creamos el contenedor y santo remedio, pero seguimos necesitando crear y desplegar el contenedor con el software asociado a éste.

Serverless computing

La mínima expresión de aislar nuestro código del resto del mundo es lo que se denomina Serverless computing, que en pocas palabras es tomar nuestro código y ponerlo en un lugar donde simplemente funciona, sin servidores, ni software adicional, ni contenedores, ni nada, si queremos más potencia movemos un slider y ya, también se conoce como FaaS (functions as a service) y AWSLamda fue lo primero que se vio por el estilo.

Azure functions

La servicio que ofrece Microsoft de Serverless computing se llama Azure Functions y es el tema del que voy a hablar en este post.

Componentes de una Azure Function

  • Código
  • Triggers / Bindings
  • Configuración

El código puede ser escrito en C#, Javascript, Python, PHP, F#, Bash, Batch o cualquier ejecutable.

Los trigger y los bindings son la forma de definir las entradas y salidar de nuestra función y cómo se dispara, un trigger define cómo se dispara la función, solo pude haber un único trigger por función los bindings son los datos de entrada y de salida si los ubiese, éste es el listado de bindings y triggers actualmente soportados.

 

image

La configuración es donde definimos todo lo que necesita nuestra app que es externo, como librerías de terceros, Azure functions soporta NuGet y NPM.

Creando nuestra primera Azure function

Hoy por hoy el soporte para crear Azure functions desde Visual Studio no es tan bueno, así que vamos a hacerlo desde el portal

image

Creamos la función C# y colocamos el siguiente código:

using System.Net;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
	dynamic data = await req.Content.ReadAsAsync<object>();
	string name = data?.name;
	return req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
}

En este sencillo ejemplo hay un par de cosas interesante: primero el mensaje de respuesta es una Task, es decir, es asincrónico y dentro del código utilizamos req.Content.ReadAsAsync y lo asignamos a dynamic para poder leer la información pasada  por POST como un JSON.

Probar la función desde el portal

image

En este caso podemos configurar el cuerpo del request y probar el resultado.

Si vamos al panel de la izquierda podemos ver algunos detalles interesantes, por ejemplo el trigger de la función

 

image

 

En este caso nuestro trigger es del tipo HTTP request, es decir nuestra función solamente se ejecuta cuando llega un request HTTP, como vemos hay otras muchas opciones para modificar, como los verbos HTTP permitidos, uno interesante el el Mode, el cual puede ser Standard como ahora o un Webhook.

Si hacemos click en Advanced Editor vemos la configuración avanzada, básicamente todos los parámetros se configuran a través de un JSON.

{
  "disabled": false,
  "bindings": [
    {
      "authLevel": "function",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in"
    },
    {
      "name": "return",
      "type": "http",
      "direction": "out"
    }
  ]
}

 

Invocar las funciones desde internet

Haciendo click en Get function URL vemos la URL pública de la función junto con la clave de acceso por defecto

image

Podemos regenerar la clave o agregar otras cuando queramos, entonces con la URL hacemos una pequeño formulario y probamos la función, pero antes cambiamos nuestra función para que lea los parámetros que envía el formulario de este modo

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
  string name = req.GetQueryNameValuePairs()
    .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
    .Value;
        
  return req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
}

gracias al método GetQueryNameValuePairs permite recuperar los parámetros que legan por query string.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <form method="get" action="https://functionslgm.azurewebsites.net/api/HttpTriggerCSharp1">
        <input type="text" name="name" />
        <input type="hidden" name="code" value="HctmiZNEOjyLTNm7uVZCUynbScU2lEsXDrKvO4AJEIwAwtaVxu14vw==" />
        <input type="submit" value="Enviar" />
    </form>
</body>
</html>

Un simple formulario para enviar el parámetro name y la clave en el elemento hidden, hacemos click en Enviar y listo.

image

Por supuesto que es un ejemplo muy simple, pero lo que acabamos de hacer es procesar un request remoto simplemente escribiendo 4 líneas de C# y nada más.

Más adelamente vamos a ver más detalles sobre Azure functions, por ahora lo dejamos acá.

Nos leemos.