Chapter 3 The politics of health care reforms
3.4 The Debate between the single-payer and multi-payer system
Tras la irrupción de NodeJS como framework para el lado del servidor, multitud de desarrolladores y empresas formaron una gran comunidad de desarrollo. Esta
comunidad tiene como objetivo potenciar las características del framework y dar difusión a la tecnología.
TJ Holowaychuk es uno de los miembros más destacables de esta comunidad. A participado en más de quinientos proyectos opensource relacionados con NodeJS. Algunos de los más destacables pueden ser nuevos frameworks de testeo y módulos de terceras partes para NodeJS.
Su mayor logro o contribución a la causa es Express. Módulo de NodeJS orientado al desarrollo de aplicaciones web, tan potente que hoy en día se utiliza con frecuencia como otro framework, especializado en entornos web.
Proporciona una eficiente gama de funcionalidades necesarias en toda aplicación web. En su elaboración se tomó como referencia otro módulo implementado por terceras partes, llamado Connect. Express utiliza Connect para el establecimiento de conexiones web, haciendo uso del protocolo HTTP. Por otro lado también utiliza la misma arquitectura de middlewares.
Para entender mejor como Express puede establecer un servicio web, haciendo uso de una arquitectura de middlewares, es necesario ofrecer detalles de las especificaciones de Connect, otro módulo NodeJS utilizado comúnmente para el establecimiento de servicios web.
Connect es un módulo de NodeJS implementado también por terceras partes. Hace
uso a su vez de otro módulo de NodeJS llamado http, que se encuentra compilado en el núcleo de NodeJS. La empresa privada de la implementación de Connect es Sencha Labs.
Este módulo fue implementado, con la intención de elaborar un software que fuera capaz de interceptar las peticiones, que un usuario con un navegador pudiera hacer a una aplicación web, en pleno proceso de ejecución en servidor. El módulo también es capaz de procesar la petición, asignando una función de código fuente para que realice el correspondiente cometido.
Para asignar a una función, como encargada de elaborar la respuesta ante una petición concreta, hace uso de un API previamente implementada por el desarrollador. Cada una de las funciones encargadas de elaborar la respuesta ante una petición concreta, se le denomina middleware.
Cuando una petición HTTP se genera desde una dirección en concreto, Connect revisa la URL asociada a la petición y sus parámetros. Posteriormente esta información se cede a un middleware y se elabora la respuesta.
La arquitectura de middlewares de Connect permite la cesión de información entre ellos. Un middleware puede utilizarse para preprocesar la información de una petición y el resultado de la función asociada a este middleware, se puede ceder a otro middleware encargado de satisfacer la petición y elaborar la respuesta.
La forma en la que Connect recibe una petición, la procesa y elabora la respuesta, es una ejecución secuencial de funciones asociadas a diferentes middleware. Cada middleware se encuentra especializado en una única tarea del proceso. En primer lugar la información de una petición es recibida por un objeto del módulo, llamado
dispatcher.
Este dispatcher o dispensador, evalúa cada petición y decide la secuencia de middlewares que tienen que ser ejecutados para generar la respuesta correcta. Para entender mejor este flujo, la siguiente ilustración aclara mejor los conceptos.
El flujo especificado corresponde al de una aplicación Express, pero como este módulo se apoya en Connect para tramitar estas operaciones, los flujos se gestionan de la misma forma en los dos módulos.
El ejemplo indica el flujo de ejecución de middlewares tras una petición de login realizada, previo procesamiento de la petición por el objeto dispatcher. Cada middleware intermedio hace uso de un método del módulo Connect, llamado next(). Este método permite realizar la llamada al siguiente middleware. La cesión de información al siguiente middleware se realiza haciendo uso de un objeto llamado
request, que se define con más detalle en la siguiente subsección del documento.
Finalmente, el último middleware que forma la respuesta utiliza un objeto llamado
response, para almacenar el contenido de la respuesta en él, comúnmente en formato
JSON o XML. De igual forma que ocurre con el objeto request, este objeto se describe con mayor detalle en la siguiente subsección de la memoria.
La aplicación Connect que aparece en la ilustración es una aplicación web muy simple, en la que un servidor responde con la frase Hello World o Goodbye World en función de la URL que el cliente web utiliza en la petición.
Existen tres middlewares encargados de procesar peticiones HTTP. Dos de ellos, están especializados en elaborar la respuesta que el servidor proporciona ante determinadas peticiones. Estos dos middlewares se llaman helloWorld y goodbyeWorld. Existe otro middleware, que se encarga de hacer procesamientos intermedios,cuando se generan determinadas peticiones. Este middleware se llama logger.
Para crear la aplicación Connect se genera un objeto llamado app, que se utiliza como referencia para hacer uso de las funcionalidades que el módulo Connect de NodeJS ofrece. Para definir los middlewares encargados de atender peticiones, e incluso asociar cada middleware a determinada URL desde la que se hace la petición, se hace uso de un método de módulo Connect llamado app.use().
El orden de definición de middlewares y su asociación con determinadas URLs, establece la secuencia de ejecución de middlewares de la aplicación, por cada petición recibida.
Como se puede observar, cada petición pasa siempre por el middleware logger, que se ejecuta en primer lugar. Posteriormente, en función de la URL utilizada para hacer la petición, se ejecuta un middleware que elabora la respuesta del servidor.
La definición de la secuencia de middlewares a ejecutar, es clave para elaborar una respuesta adecuada ante cada petición. En cada petición, la secuencia de middlewares se ejecuta según una cola FIFO (first-in-first-out o el primero en ser definido es el primero que se ejecuta). A lo largo de la ejecución de middlewares, puede existir transferencia de información entre ellos, hasta llegar a un middleware de la secuencia, encargado de elaborar la respuesta a la petición.
Express utiliza la misma arquitectura de middlewares descrita anteriormente, para la elaboración de aplicaciones web. Su integración con NodeJS es muy sencilla. Sigue el patrón de integración que tiene un módulo implementado por terceras partes. En primer lugar, es necesario incluir la dependencia del módulo en el fichero package.json y posteriormente descargar el código fuente del módulo con NPM, para poder hacer uso del módulo en implementaciones.
La implementación de una aplicación básica en Express es sencilla. Por otro lado, es cierto que cuando el proyecto crece en magnitud, la complejidad del código aumenta y las implementaciones son algo menos sencillas. Tal y como ocurre con la aplicación
web de este proyecto. No obstante, para aclarar los conceptos básicos de una aplicación Express, se hace uso de un código de apoyo con menor complejidad.
Como se puede observar en la ilustración, no hay grandes diferencias en la implementación de una aplicación Express básica y una aplicación Connect.
Se define una referencia llamada app, con la que se puede hacer uso del conjunto de funcionalidades que ofrece el módulo Express. Se hace uso del método app.use() para definir un middleware, que proporcione una respuesta ante una petición realizada desde la ruta “/”. Posteriormente se levanta el servidor en el puerto 3000, haciendo uso del método app.listen(). Finalmente se exporta la referencia app, por si es necesaria su utilización en otro módulo de la aplicación.
A destacar en el middleware implementado, los parámetros req y res correspondientes a los objetos request y response. Son algo diferentes a los mismos objetos del módulo Connect. Express encapsula parte de la configuración del protocolo HTTP para elaborar la respuesta, dentro del objeto response.
De esta forma es mucho más sencillo elaborar la respuesta que proporciona un middleware, sin la preocupación de definir las cabeceras correspondientes, en función del tipo de dato a retornar. Todo ello se realiza haciendo uso del método res.send().