La “solución” en Visual Studio: de solución nada, solo problemas

Desde sus inicios Visual Studio contiene el concepto de solución como grupo de proyectos. Es más, no puedes abrir un solo proyecto siempre debes abrir una solución (si abres un proyecto VS crea una solución que contiene el proyecto de forma automática).

Como idea, hace años no estaba mal. Y que quede claro: en según que contextos puede seguir siendo válida. Pero en muchos otros, solo aporta problemas: el desarrollo de software ha cambiado mucho, las formas en como usamos los IDEs no son iguales, pero VS sigue anclado a este obsoleto sistema de gestionar proyectos.

Continúa leyendo La “solución” en Visual Studio: de solución nada, solo problemas

Algunas pinceladas sobre como arquitecturar tu WEB/API

El otro día Antíoco Llanos lanzaba el siguiente tweet:

(Siempre las mismas dudas. Que dependa mi capa de negocio de EF para usar sus IDbSet o no… ¿abstraer la abstracción?)

Contesté yo con algunas sugerencias y eso derivó en otra conversación paralela, así que me parece una buena idea poner algunas pinceladas sobre como podemos abordar ese aspecto. Por supuesto y como digo siempe: no hay balas de plata y no existe la arquitectura para todo. Cada proyecto debe analizarse para valorar la arquitectura a abordar, o arquitecturas porque se pueden usar distintas en un mismo proyecto. Así, este post no tiene más pretensión que contarte algunas ideas, pero las conclusiones que saques de ellas son cosa tuya 😉

Continúa leyendo Algunas pinceladas sobre como arquitecturar tu WEB/API

ASP.NET–Comprueba la disponibilidad de tus servicios

Si desarrollas una aplicación en ASP.NET y/o ASP.NET Core, te puede interesar una nueva librería que ha sacado el equipo de .NET: HealthChecks. Esa librería (muy sencilla) contiene lo que necesitas para poder validar que un determinado recurso externo (SQL Server, API remota, etc) está funcionando y también para que decidas lo que significa que un recurso “está funcionando”.

Continúa leyendo ASP.NET–Comprueba la disponibilidad de tus servicios

C# 7–Default method implementation?

El otro día estuve hablando con Joan Jané, sobre la funcionalidad que se está valorando para C#7 o (probablemente, dado su estado) más adelante. A falta de un nombre mejor llamaré a esa funcionalidad “Default method implementation” porque así se conoce en Java, donde esa funcionalidad ya existe.

Joan y yo teníamos puntos de vista totalmente opuestos a dicha característica, mientras que para mi era un añadido muy interesante al lenguaje, Joan se alineaba más con las tesis que Fernando Escolar expone en un post en su blog. Para Fer, esa feature es la peor idea que ha tenido Java en los últimos años. A mi me da la sensación que verlo así es no entender exactamente que añade esa característica y analizarla desde una posición demasiado rígida. Joan argumentaba problemas relacionados con SOLID, generalmente con el SRP y con la segregación de interfaces. En este post voy a comentar lo que, desde mi punto de vista, permitiría esa característica de estar disponible. Y por qué, no solo no es una mala idea, si no, a priori, todo lo contrario (tanto en Java como en C# por más que se empecine Fer en decir lo contrario).

Continúa leyendo C# 7–Default method implementation?

Docker para el desarrollador de asp.net (iii)

En el post anterior vimos como empaquetar y desplegar en Docker una sencilla aplicación (un hello world) en asp.net core. En este post vamos a ver como desplegar en Docker una aplicación asp.net core (con sus controladores y vistas) y también ver como lo podemos usar usando una imagen base que no tenga el SDK, solo el runtime.

¡Vamos allá!

Continúa leyendo Docker para el desarrollador de asp.net (iii)

Docker para el desarrollador asp.net (ii)

Seguimos con esta sobre el uso de Docker desde el punto de vista de un desarrollador asp.net (core). En este caso vamos a construir nuestra primera imagen Docker.

Nota: Visual Studio 2017 incorpora de serie las Docker Tools que automatizan todo lo que veremos en estos artículos. Tiempo tendremos, más adelante en esta serie, de hablar de las Docker Tools. La razón de hacerlo primero todo “manual” es porque el objetivo de esta serie es ayudarte a que entiendas Docker, no presentarte el “botón mágico” que se encarga de todo. Yo, es que soy de la vieja escuela: me gusta entender las cosas (al menos hasta donde puedo).

Continúa leyendo Docker para el desarrollador asp.net (ii)

Docker para el desarrollador asp.net (i)

Buenas! Vamos a empezar una serie de posts dedicadas a Docker desde el punto de vista de un desarrollador asp.net. Empezaremos por lo más básico pero nos iremos adentrando un poco en el mundo de Docker. El objetivo es que terminemos teniendo unos conocimientos medios que nos permitan entender que es Docker, como funciona, qué ventajas tiene y como usarlo (y cuando) en arquitecturas más complejas donde haya más de un contenedor. Pero… empecemos por el principio.

Continúa leyendo Docker para el desarrollador asp.net (i)

MVC6–Recibir un GUID en el cuerpo de la petición

Hoy me he encontrado un controlador MVC6 con la siguiente acción:

[HttpPut]
[Route("{userid:int}/faceprofile")]
public async Task<IActionResult> SetFaceProfileId(int userid, [FromBody] Guid id)

Claramente su autor esperaba que pudieramos poner un Guid en el cuerpo de la petición y eso funcionaría… Pero, ¿como debe mandarse?

Continúa leyendo MVC6–Recibir un GUID en el cuerpo de la petición

Azure Functions – Serverless Backends

Últimamente se oye bastante hablar de serverless backend. Esta expresión puede sugerir implementaciones de servidor sin… servidor. Pero no, la realidad es que dicha expresión define una arquitectura en la cual no nos preocupamos para nada del servidor. Existir, existe, pero es totalmente transparente (o casi) para nosotros.

Es una astracción superior a la que ofrece un sistema PaaS. Tomemos un ejemplo de PaaS en Azure, como las web apps. Efectivamente, con una web app tenemos un nivel de abstracción relativamente alto: nos olvidamos de instalar un servidor en una máquina virtual y nos olvidamos de muchas tareas de administración. Con muy poco esfuerzo por nuestra parte podemos tener nuestra aplicación o API HTTP desplegada en una aplicación web con capacidad de escalar según sea necesario. Pero, a pesar de esas facilidades, seguimos viendo claramente un servidor: desplegamos en la webapp, configuramos la webapp, escalamos la webapp. El servidor sigue estando presente, solo que es mucho más sencillo de configurar que el sistema equivalente en IaaS u on-premise.

En un sistema tipo serverless backend, la única tarea realmente indispensable que hay que hacer es subir código y este se ejecuta de forma casi inmediata. No hay apenas configuración. No vemos cual es el servidor subyacente que ejecuta el código. El concepto de servidor “desaparece”: es nuestro código y se ejecuta. No hay que preocuparse de nada más. PaaS vino para simplificarnos la vida respecto IaaS y el serverless backend viene para simplificarla todavía más.

En Azure este paradigma se encarna mediante las Azure Functions que son exactamente lo que su nombre indica: funciones de código que se suben a Azure y se empiezan a ejecutar.

Creando una función de Azure

La creación no podría ser más sencilla, podemos codificar nuestra función directamente desde el portal de Azure.

Lo primero que debemos hacer es agregar una Function App. No es más que un contenedor donde vamos a tener todas nuestras funciones. Para ello desde el portal de Azure pulsamos agregar un nuevo elemento, tecleamos “functions” en el buscador y nos aparecerá la opción:

clip_image002

Pulsamos el botón de Create, rellenamos los datos (básicamente el nombre de nuestra function app) y ya podemos empezar.

Con esto no hemos creado ninguna azure function, solo hemos creado su contenedor. Una vez esté creado ya lo veremos dentro del resource group que hayamos elegido:

clip_image003

Si abrimos la function app (el icono con el rayo) se nos abre la interfaz para añadir funciones directamente desde el portal de Azure:

clip_image005

Lo primero que se nos pide es que tipo de función queremos añadir. Básicamente tenemos tres tipos posibles:

1. Timer: Funciones que se ejecutan basadas en un temporizador. Se pueden ejecutar cada 5 minutos, cada día a las 15 en punto o los domingos las 8 de la mañana por poner unos ejemplos.

2. Data Processing: Funciones que se ejecutan en base a triggers lanzados por otros elementos de Azure. Hay una gran variedad de triggers disponibles tales como que se cree un fichero en un storage, que llegue un evento via service bus o un elemento nuevo en una cola de Azure, entre otros.

3. Webhook + API: Funciones que se integran con APIs externas que soporten webhooks. P. ej. Github los soporta, así que sería posible hacer una función que se ejecutara cada vez que alguien comentara una issue en GitHub.

En función del escenario elegido (y del lenguaje C# o JavaScript), veremos el código inicial de nuestra función. P. ej. la siguiente captura muestra el código para una función de tipo “Data Processing”:

clip_image007

Podemos usar el propio portal para configurar los triggers que dispararán dicha función. Para ello, pulsamos sobre la opción Integrate de la barra de la izquierda, y de forma totalmente gráfica podremos configurar los triggers de nuestra función:

clip_image009

Además del trigger podemos especificar entradas opcionales para nuestra función (p. ej. un documento en una cola de Azure, un documento de DocumentDb, …) y también salidas opcionales (fichero a escribir, mensaje a mandar,). Estas entradas y salidas se reciben como parámetros en nuestra función.

Como se ha comentado el código se escribe en el portal:

clip_image011

Desde el propio portal podemos guardar la función, lo que automáticamente la compilará. La función se guarda siempre en un fichero run.csx (para el caso de C#) o index.js (para el caso de JavaScript (NodeJS)).

Por supuesto es posible usar cualquier editor para crear no solo el fichero run.csx (o index.js) y subir luego el contenido a Azure. Al subirlo, automáticamente la función se compilará y estará lista para ejecutarse. Para subir el contenido se puede usar Git o incluso FTP.

La configuración (los triggers que disparan la función, o cada cuando se ejecuta, sus entradas y sus salidas) se guarda en un fichero json. Podemos ver su contenido si pulsamos el botón “Advanced Editor” dentro de la sección “Integrate”. La siguiente captura muestra el editor gráfico:

clip_image013

Si pulsamos sobre el botón “Advanced editor” vemos el contenido del fichero json:

clip_image015

Desplegar una Azure function es desplegar el fichero run.csx (o index.js) y su fichero json de configuración. No es necesario hacer nada más. No hay que compilar nada, en caso de ser necesario la compilación ocurre en Azure.

Webjobs y Azure functions

Azure functions es una evolución de los actuales Webjobs. Muchas de las tareas que se automatizaban en Webjobs pueden automatizarse en Azure functions. La diferencia fundamental es, básicamente, de concepto. Los Webjobs son un escenario PaaS, donde el servidor (una Webapp) es claramente explícito. El webjob se despliegua de forma tradiciona y la webapp que lo contiene se configura como cualquier otra.

Una Azure function se ejecuta a través de una webapp. Se parece mucho a los webjobs, pero esto para nosotros es totalmente transparente. A pesar de que es posible hacerlo, no necesitamos por norma general acceder a la webapp subyacente. En general, las Azure functions evolucionan los webjobs y los llevan a un nuevo nivel de simplicidad.

Resumiendo

Azure functions es la implementación del paradigma serverless backend, en el cual el servidor queda difuminado hasta casi poder ser ignorado. Una Azure function es una porción de código (realmente una función) que se ejecuta como causa de un disparador (puede ser un temporizador, una acción sobre un elemento de Azure (tal como un mensaje en un service bus) o la llegada de un webhook para integrarnos con cualquier API que los soporte). La función puede realizar cualquier operación que sea necesaria (p. ej. comprimir imágenes subidas a Azure, periódicamente limpiar una tabla en una base de datos SQL Azure o cualquier otra tarea). La ejecución de una Azure function puede realizar una tarea que actúe como disparador de otra Azure function, dando lugar a escenarios complejos.