Tapestry 5, parte 1 - Introducción Histórica

Este es un primer intento de explicar las diferencias entre Tapestry y JSP. De hecho no solamente con JSP sino con los otros frameworks que son basados en el esquema de JSP. Esta vez voy a empezar con algo de historia, para ponernos en contexto de por qué Tapestry funciona como funciona (aunque tal vez no llegue a esa parte en este post).

En tiempos inmemoriales, a mediados de los 90's, cuando empiezan a popularizarse los web servers, solamente sirven contenido estático. Los primeros contenidos dinámicos fueron por medio de programas llamados CGI's, Common Gateway Interface, que consistía en que el web server le pasaba la URL y datos de la petición HTTP a un programa en UNIX, que lo leía del STDIN, y podía imprimir a STDOUT cualquier salida; ésta era devuelva por el web server al navegador. Esto es muy ineficiente porque cada petición ejecuta un programa y un programa medio complejo puede tardar bastante en ejecutarse, utilizar recursos, etc (por ejemplo cuando el CGI ya hacía conexiones a base de datos, etc).

La respuesta de Java a los CGI's fueron los servlets, que consisten simplemente en extender una clase Java, implementar un par de métodos (doGet() y doPost(), opcionalmente a un método de inicialización y otro de finalización), y listo; la clase se pone dentro de un contenedor (por ejemplo Tomcat o Jetty) y entonces las peticiones HTTP que llegan al contenedor (que normalmente también tiene un web server integrado) se pasan al servlet cuando la URL es la indicada, se ejecuta el método correspondiente al GET o POST de HTTP y ya. El servlet es responsable de imprimir a un OutputStream cualquier salida.

Esto es bastante engorroso y por eso después surgieron los JSP's, que consisten en hacer un archivo de texto con código HTML pero con ciertas extensiones especiales (los infames tags de <% codigo %>, <%= evaluación %>, etc). De esta manera se simplifica la tarea más común de los servlets, que era devolver una página con HTML generada dinámicamente. Pero surge un nuevo problema, que ya no es tan trivial de resolver: se rompe el esquema MVC, separación de capas o como le quieran llamar. Resulta que ahora con JSP's se propicia el código spaghetti, porque tenemos intercalado HTML (que es GUI a final de cuentas) y código Java (que es todo lo demás: control, modelo, validaciones, lógica de negocio, etc etc etc). Además el control de flujo entre JSP's y servlets se tiene que hacer a muy bajo nivel, invocando redirecciones y cosas así. Pasar datos de un JSP a otro es una pesadilla. Guardar datos en sesión tampoco es muy sencillo que digamos. Hay que teclear bastante código para cosas muy básicas.

Es en este punto que comienzan a salir cosas como Struts y JSTL, para resolver o aliviar estos problemas. Con JSTL ya tenemos una bola de tags adicionales que podemos usar para no tener que meter un if en Java sino que ahora es un tag, o tags para ciclos y algunas otras cosas. Pero no nos permite aún así hacer aplicaciones más robustas. Struts por su parte se enfoca a resolver el problema del manejo de datos, capturar datos en una página, validarlos, pasarlos a otra página si son válidos o devolver error si no lo son, etc.

Y ahora empezamos con XMLitis; para configurar Struts (al menos en sus primeras versiones) se necesita muchísimo XML. Si no funciona, es que le falta XML. Con JSTL es igual; si tenemos tags propios, hay que aventar XML a la config de la aplicación para indicar dónde están, cómo funcionan, etc. Si algo no funciona, faltó XML. Usar XML es como usar violencia; si no resuelve el problema entonces hay que usar más.

Más o menos paralelo a los esfuerzos de Java, están los esfuerzos de Microsoft con sus ASP's (Application Server Pages, que de hecho son muy similares a los JSP's y que de hecho Sun copió el diseño para los JSP's, aunque salieron después de los servlets porque en esos tiempos todavía MS pensaba que iba a vencer a internet haciendo su propia red llamada la Microsoft Network) y el esfuerzo de NeXT con WebObjects. De Microsoft ni hablemos; pero WebObjects merece una mención especial en esta historia porque técnicamente tiene mucho mérito.

La arquitectura de WebObjects (que salió en 1996) es así: se corre una aplicación hecha en Objective-C y el web server le pasa peticiones a esta aplicación. La aplicación tiene páginas y componentes. Una página de WebObjects está hecha de 3 partes: Un archivo de HTML, común y corriente en su mayor parte, excepto por ciertos elementos que decían WEBOBJECT, por ejemplo en un Hola.html podíamos tener algo así:

<WEBOBJECT NAME="Hola"></WEBOBJECT>

Eso por sí mismo no nos dice nada. Pero la segunda parte de la página es un archivo con extensión wod, que trae las definiciones de los objetos incluidos en el HTML:

Hola: WOString {
  value = horaActual;
}

Y finalmente, tenemos el código. El código originalmente podía ser una clase en Objective-C o un archivo en un lenguaje llamado WebScript, que era interpretado en tiempo de ejecución. Para la versión 4 (1999) ya soportaban hacer la página también en Java. De modo que en Java podríamos tener algo así:

public class Hola extends WOComponent {
  public String getHoraActual() {
    return new Date().toString();
  }
}

Sé que con un ejemplo tan simple, parece menos engorroso tener un solo archivo hola.jsp y poner algo como <%= new Date() %> pero al momento de empezar a ver ligas entre páginas y que se pasen parámetros y cosas así es cuando ya saben que se complica la cosa y por eso salieron tantas soluciones al mismo problema. Aquí solamente quiero enfocarme a la manera tan diferente de hacer aplicaciones web, porque Tapestry comenzó siendo un framework de software libre inspirado en la arquitectura de WebObjects.

Algo interesante de este esquema: no solamente se pueden desarrollar páginas sino que se pueden hacer componentes, que son fragmentos de páginas que van incluidos dentro de otras páginas. Un ejemplo (sin meterme a código) es que se podía por ejemplo hacer un componente que despliega los atributos de un objeto, o el nombre de un usuario, cosas así, y se incluye en varias páginas. Los componentes pueden recibir parámetros del componente que los contiene (porque puede haber componentes dentro de componentes dentro de componentes, etc).

En el próximo post ya me voy a saltar a Tapestry 5 y su arquitectura actual, espero poder incluir un par de ejemplos sencillos. Por ahora concluyo mencionando sus características principales:

- Requiere un mínimo de configuración en XML (solamente un par de cosas que se incluyen en el web.xml de la aplicación web)
- Las páginas se dividen en dos archivos: Uno con el HTML y otro con la clase en Java que contiene toda la funcionalidad. Las páginas en Java con POJOs, no es necesario heredar de ninguna clase ni implementar ninguna interfaz.
- El esquema de funcionamiento se basa en eventos, es decir, una liga o una forma pueden generar uno o varios eventos distintos que se pueden interceptar en la página en Java.
- Las páginas pueden tener varias propiedades que apunten a componentes comunes de la aplicación; el manejador de inyección de dependencias de Tapestry se encarga de configurar la página, basado en las anotaciones que se pongan a las variables de la clase en Java.
- Permite por una parte tener una abstracción del ciclo de petición-respuesta típico de aplicaciones web pero por otra parte permite tener un control de bajo nivel tan refinado como sea necesario.
- Cualquier página puede ser a su vez un componente y ser incluido dentro de otras páginas o componentes; puede recibir parámetros del componente que lo incluya.
- Tiene buena integración con AJAX, permite respuestas parciales en las páginas y componentes, maneja datos en formato JSON, incluye la librería de JavaScript Prototype.
- Durante el desarrollo se pueden modificar las clases Java y la siguiente invocación va a recargar la clase sin necesidad de reiniciar la aplicación o recargarla por completo, acelerando así la velocidad del desarrollo.

Siguiente: Introducción al framework Tapestry 5

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Buenisimo

Ezamudio, me parece muy bacano que hallas conseguido el tiempo para compartirnos tus experiencias en este Famework, que a la fecha me a parecido muy interesante.

Estoy bastante entusiasmado con tus intensiones de continuar hablándonos de Tapestry. Estaré muy pendiente a próximas publicaciones.

Gracias

Imagen de Jvan

Bastante interesante, me

Bastante interesante, me agrada la introducción que has hecho, esperamos la segunda parte. :p

Imagen de benek

Tapestry

Wow Enrique! Desde hace tiempo que venía esperando un texto introductorio de Tapestry de parte tuya o de iberck... Que bueno que te decidiste a crearlo, está excelente.

Espero con ansia la siguiente entrega!

Gracias.

Imagen de javadicto

Muy bueno.

Muy buena introduccion. Espero en los proximos dias tener un poco mas de tiempo para dedicarselo a este Framework.

Imagen de ezamudio

Segunda parte

Gracias por sus comenarios.

Ya publiqué la segunda parte, con cosas muy básicas pero que ya abre la puerta para empezar a ver después cosas más interesantes.