miércoles, 18 de septiembre de 2013
Pues seguimos con esta serie de artículos sobre OWIN que comenzamos unos días atrás con una introducción conceptual de esta especificación, y hoy vamos a centrarnos en Katana, la implementación de Microsoft de este interesante estándar.
Primero explicaremos en qué consiste este proyecto, sus componentes principales, y después veremos la configuración y funcionamiento de este tipo de sistemas, acercándonos ya un poco al nivel que tanto nos gusta, el código fuente ;-)
Si es vuestro primer acercamiento al mundo de OWIN y Katana, os recomiendo que leáis previamente el primer artículo de la serie, Introducción a OWIN.
Conoce tu Katana, pequeño saltamontes
Katana (katanaproject.codeplex.com) es un proyecto open source liderado por Microsoft Open Tech que implementa un conjunto de componentes y herramientas destinadas a facilitar el alojamiento y desarrollo de aplicaciones web basadas en la especificación OWIN. Se distribuye bajo licencia Apache 2.0, e incluso se ha permitido expresamente el uso de los binarios en plataformas no Windows, algo que no estaba contemplado en las primeras versiones.En Katana todos los componentes están diseñados teniendo en mente tres características básicas:
- Portabilidad, que se consigue evitando el acoplamiento entre componentes. Esto hace que una pieza pueda ser sustituida por otra que cumpla su misma función, aunque se traten de implementaciones distintas, o incluso de plataformas distintas. Podremos ejecutar aplicaciones en cualquier tipo de host, servidor, o sistema operativo, siempre que el framework en el que estén desarrolladas sea compatible OWIN y se dispongan de los adaptadores apropiados.
- Modularidad, que huye del enfoque tradicional del framework monolítico con decenas de opciones y funcionalidades (de las cuales al final sólo usábamos dos ;-)) y se concentra en crear componentes muy pequeños y especializados. El desarrollador será el que elija cuáles de ellos necesita para sus aplicaciones.
- Escalabilidad, que se consigue aligerando peso de las aplicaciones al usarse sólo los módulos necesarios, muy especializados y eficientes, y el uso intensivo de asincronía.
El camino de la Katana
Su andadura comenzó en 2010 en GitHub, cuando todavía la especificación se encontraba en borradores muy preliminares.La versión 1.0 no vio la luz hasta febrero de 2013, y comenzó a ser utilizada para alojar aplicaciones Signalr, Nancy o FubuMVC, y sobre todo en escenarios self-hosting (hosting dentro de procesos no ASP.NET, como una aplicación de consola o un servicio Windows).
En la actualidad se encuentra en v2.0-RC. Es decir, queda poco para que esté disponible; previsiblemente acompañará al resto de productos cuyas nuevas versiones que llegarán este otoño, como WebAPI 2.0, SignalR 2.0, o Visual Studio 2013.
Se puede, sin embargo, descargar las versiones prerelease a través de Nuget mientras la versión final aterriza activando este modo en el IDE, o añadiendo el switch
–pre
a las instrucciones de consola como install-package
o get-package
.Piezas de la Katana
El proyecto Katana está compuesto por un buen número de componentes independientes que podemos incluir en nuestros proyectos cuando sean necesarios. En general, incluye:- Hosts. Como recordaremos, básicamente los hosts eran los procesos que ejecutaban las aplicaciones. Katana viene acompañada componentes que permiten alojar servicios basados en OWIN sobre IIS/ASP.NET, en cual tipo de proceso mediante self-hosting, e incluso una aplicación de línea de comandos (OwinHost.exe) para lanzar servicios.
- Servers, que sabemos que son los componentes que escuchan las peticiones. Actualmente hay servidores basados en HTTP listeners de .NET, ideales para escenarios self-hosting, así como adaptadores para “engancharse” a ASP.NET/IIS.
- Módulos middleware de uso genérico, como módulos de compresión, seguridad (cookies, basic, Active Directory, OAuth, etc.), acceso a archivos estáticos, soporte CORS, y algunos más).
- Adaptadores para frameworks existentes como SignalR o WebAPI.
- Infraestructura para el arranque y configuración del pipeline OWIN que implementa el procedimiento de startup definido por el estándar y que vimos en el post anterior.
- Infraestructura para la creación de nuevos middlewares o adaptadores de frameworks personalizados.
Aparte, en Nuget existen otros paquetes interesantes relacionados con OWIN, aunque no forman parte de Katana, y es interesante echar un ojo de vez en cuando.
Empuñando la Katana
Hace unos días hablábamos de que OWIN define claramente cuál es el procedimiento de arranque de las aplicaciones que se basan en esta especificación. Por recordarlo rápidamente, poco más o menos es así:- Host y Server cargan datos de entorno e inicialización en un diccionario.
- Se ejecuta el código de arranque de la Aplicación suministrándole dicho diccionario. La aplicación utiliza el diccionario para configurar su pipeline, es decir, la cadena de módulos que procesarán las peticiones.
- Se inicia el Server, quedando a la espera de peticiones. Cada petición será procesada a través del pipeline creado por la Aplicación.
- En aplicaciones web, utilizaremos el paquete Microsoft.Owin.Host.SystemWeb para adaptar ASP.NET/ISS a OWIN. No tendremos que encargarnos de iniciar el Host ni el Server.
- En otras aplicaciones .NET (apps de consola, forms, servicios windows…), usaremos self-hosting y el paquete Microsoft.Owin.Host.HttpListener. En este caso, tendremos que encargarnos manualmente de crear el Host e iniciar el Server para poder comenzar a prestar servicios.
En cualquier caso, como desarrolladores de aplicaciones, siempre tendremos que configurar el pipeline de proceso de peticiones.
Por seguir la convención propuesta por Katana, la configuración la realizaremos en el método
Configuration()
de una clase llamada Startup
que se encontrará en el espacio de nombres raíz de la aplicación. En realidad, más adelante veremos que no es algo tan rígido, y podemos modificar a nuestro antojo esta ubicación.Generalmente, una la clase de inicialización OWIN tiene la siguiente pinta:
public class Startup { public void Configuration(IAppBuilder app) { // App & pipeline configuration } }El parámetro
IAppBuilder
que recibe este método es el punto central desde donde tendremos acceso al diccionario de entorno poblado por el Host y el Server, y configuraremos el pipeline. Su definición es la siguiente:public interface IAppBuilder { IDictionary<string, object> Properties { get; } IAppBuilder Use(object middleware, params object[] args); object Build(Type returnType); IAppBuilder New(); }Los métodos
Build()
y New()
son utilizados de forma interna, y también pueden ser útiles para cuando hayamos conseguido el cinturón negro, por lo que no los veremos ahora. Más interesantes y asequibles en este momento son Properties
y Use()
.Properties
contiene el diccionario de entorno, donde podemos encontrar información interesante como el nombre de la aplicación, información sobre el host, factorías de logging y trazas, características del servidor y algunas cosas más. El aspecto que tiene en ejecución es el siguiente:El método
Use()
, definido también sobre el interfaz IAppBuilder
, es el que permite añadir sucesivos middlewares al pipeline, que internamente se irán introduciendo en una lista que compone la cadena de módulos responsables de procesar las peticiones. Aunque se puede utilizar directamente el método definido en el interfaz, lo habitual es usar otras sobrecargas y métodos extensores que lo pongan más fácil. Por ejemplo, la configuración de una aplicación podría ser la mostrada a continuación; ojo, que los middlewares mostrados son ejemplos, no existen:public class Startup { public void Configuration(IAppBuilder app) { app.Use<LogginMiddleware>(); app.Use<IpFilterMiddleware>(); app.Use<StaticFileMiddleware>(); } }Con esta configuración estaríamos indicando que cuando llegue una petición, y tras poblar el diccionario con datos de la misma y su contexto, se invocará al módulo
LogginMiddleware
. Éste podría, por ejemplo, guardar determinados datos de la petición en un log, y una vez terminado su trabajo, él mismo invocaría al siguiente módulo en el pipeline, IpFilterMiddleware
.IpFilterMiddleware
podría, por ejemplo, comprobar si la IP origen de la petición se encuentra en un rango determinado. En caso negativo, retornaría al cliente un error HTTP 403 y la petición no continuaría ascendiendo por el pipeline. En caso afirmativo, en cambio, invocaría al siguiente módulo del pipeline, StaticFileMiddleware
, quien finalmente podría retornar el contenido del archivo estático solicitado por el cliente.Observad que el proceso de una petición, en definitiva, se trata de una cadena de ejecución cooperativa de middlewares, es decir, es cada módulo el responsable de invocar al siguiente eslabón en el pipeline. Si algún módulo decide cortocircuitar el proceso, todos los que estén por arriba ni siquiera se enterarán de que la petición llegó al servidor. O si algún módulo realiza una acción sobre el entorno, otros que se ejecutan posteriormente podrían deshacerla o anularla.
Y como este artículo está extendiéndose ya demasiado, lo dejamos aquí. La próxima vez saltaremos al tatami y veremos un par de ejemplos prácticos, continuando así nuestro camino hacia el cinturón negro ;-)
Publicado en Variable not found.
Publicado por José M. Aguilar a las 8:45 a. m.
Etiquetas: katana, owin, tutorial, tutorial-owin-katana
Aún no hay comentarios, ¡sé el primero!
Enviar un nuevo comentario