Generación de operaciones CRUD para Yesod . Generación de operaciones CRUD para Yesod Jairo Gil Cardona Escuela e-mail: jairo.gil.cardona@gmail.com RESUMEN: Se desarrolló un paquete para el Framework de desarrollo web Yesod, de tal forma que sea posible generar las operaciones de acceso de datos (Crear, Modificar, Eliminar y Consultar) junto a sus respectivas vistas, a partir del modelo de datos presente en las aplicaciones desarrolladas en este Framework. PALABRAS CLAVE: Generación de código, Haskell, Yesod, DSL, aplicaciones Web. 1. INTRODUCCIÓN Los tiempos son un factor clave a la hora de iniciar un nuevo desarrollo de software; sin embargo, en muchos lenguajes y frameworks se invierte gran parte del tiempo en la construcción de las funciones de CRUD, a pesar de que dicho desarrollo es en términos generales mecánico y repetitivo. Ésta problemática ha tenido diferentes soluciones con el paso del tiempo y actualmente existen Frameworks como Yii[6] o Play[7] que ofrecen un mecanismo no solo para la generación de la lógica, sino que además generan la interfaz de usuario. Yesod en su momento no fue la excepción y contó con un generador de operaciones llamado Yesod.Helpers.Crud [1]. El cual nunca fue actualizado conforme se desarrollaron las nuevas versiones de Yesod y actualmente se encuentra obsoleto. Existe un segundo paquete llamado YesodCrud[2] el cual permite generar la lógica de las operaciones CRUD, sin embargo éste no genera interfaz gráfica y las operaciones generadas son creadas como SubSitios[3]. El paquete desarrollado busca ofrecer una nueva alternativa para la generación de operaciones de acceso de datos, permitiendo generar la lógica de las operaciones y la interfaz, sin limitar ninguna de las ventajas que ofrece el desarrollo en Yesod. Este paquete busca generar operaciones de tipo seguro en tiempo de compilación, es decir, capturando la mayor cantidad de errores antes de generar el código. Es por ello que para su desarrollo se utilizó Template Haskell [4] y Quasiquotation [5]. Al igual que Yesod y la mayoría de sus librerías este paquete se publica con licencia MIT [12] para que su uso, depuración y extensión estén disponibles. 2. Generador de operaciones CRUD 2.1 Antecedentes Existen en la actualidad diversos Frameworks que ofrecen métodos para la generación de operaciones de acceso de datos, incluyendo a Yesod que actualmente cuenta con el paquete Yesod-Crud; otros de ellos son: Yii: Framework web orientado a objetos, de código abierto, dirigido a PHP y basado en el modelo MVC, utiliza el patrón DAO para la migración de la base de datos. Incluye un asistente para la generación automática de código llamada Gii, que permite parametrizar cosas tales como las validaciones para los formularios dentro de la generación de código [6]. Synfony: Es un framework web de código abierto para PHP (Requiere PHP 5.3) basado en el modelo MVC, encaminado a reducir el tiempo de desarrollo de una aplicación web compatible con la 11 Generación de operaciones CRUD para Yesod . mayoría de gestores de base de datos. Cuenta con un sistema para la generación automática de código CRUD en función de su modelo de datos [7]. Play: es un framework web de código abierto para Scala y JAVA basado en el modelo MVC. Al igual que Synfony apunta a la productividad del desarrollador y busca reducir tiempos. Incluye un módulo para la generación del CRUD junto a sus interfaces, generando vista del formulario y una vista para listar, permite además configurar o extender el código generado, añadiendo nuevas validaciones, personalizando la interfaz entre otros [8]. 2.2 Template Haskell y Quasiquotation. Las librerías que hicieron posible el desarrollo de este generador son Template Haskell y Quasiquotation; el modo de generación de código consiste en primer lugar en convertir los parámetros “String” recibidos en cada una de las funciones en funciones y tipos de datos de Haskell, allí se valida que el nombre de la entidad enviada por parámetro exista, luego de esto se genera un árbol de derivación sintáctica[10] con la función a generar, incluyendo las funciones y tipos definidos a partir de los parámetros, una vez generado el árbol es compilado y de no presentarse errores las funciones son “generadas en el contexto de la aplicación” esto quiere decir que no se escriben en ningún archivo sino que están definidas y pueden ser usadas en el programa; pero cada vez que la aplicación es recompilada, las funciones vuelven a ser generadas. La gran ventaja de esto ofrece en comparación de escribir código en un archivo es que no se genera código si este no compila, el programador no necesita modificar código generado para implementar nuevas funcionalidades, tanto de lógica de negocio como de interfaz, y finalmente en caso de presentarse un cambio que implique añadir modificar o eliminar una de estas funciones generadas no se necesitará realizarlo a mano pasando archivo por archivo, bastará con hacer los cambios en la invocación del generador y recompilar la aplicación para que los cambios surtan efecto. En el grafico que observamos a continuación se ilustra el proceso de generación de código; de un lado tenemos la invocación del generador, el cual construye un árbol de derivación, luego este árbol se pre compilara validando la forma, el nombre del método, la entidad, entro otros, y a partir de este proceso obtendremos o un error de compilación o el método generado en el contexto de la aplicación. Cabe aclarar que el término “contexto de la aplicación” no existe ni en Haskell ni en Yesod, se a utilizado para indicar que el código Haskell generado nunca se escribe en un archivo sino que están definidos únicamente en el archivo binario .hi[14]. 3. Generador de operaciones CRUD Existen dos formas de utilizar el nuevo paquete, la diferencia radica en el código generado. En los llamados “métodos Route” se crean métodos que hacen referencia a los definidos en el archivo de rutas, mientras que en los “métodos method” no; es decir, que estos últimos deben ser invocados de forma 12 Generación de operaciones CRUD para Yesod . posterior por otro método. La diferencia fundamental entre ambos métodos es que los “métodos Route” no permiten programar funcionalidad adicional, mientras que los “métodos method” sí. Independientemente de la forma de generación que se escoja se deben tener en cuenta: Se debe definir una entidad sobre la cual se realizarán las operaciones de CRUD. Para poder generar las operaciones de crear y editar se debe definir un Aform[9] de la entidad. A continuación podemos ver un ejemplo del tipo de dato de una forma para la entidad “Entity” entityForm :: Maybe Entity -> AForm Handler Entity Para poder generar la lista de una entidad se debe definir el atributo a mostrar, este puede ser cualquier atributo de tipo Text de la entidad o cualquier función que retorne un Text. El nombre de los métodos y las rutas expuestas como servicios Rest, debe ser definido a mano y llevar por nombre, el nombre de la entidad seguido por el nombre del método (create,edit,delete,list); además para las operaciones de editar y eliminar estas deben recibir por parámetro un id de la entidad; de modo que si por ejemplo se desea generar la operación de editar para una entidad Entity, se debería definir un servicio como el que se muestra a continuación /nombreRuta/#EntityId EntityEditR GET POST 3.1 Métodos Route Estos métodos generan funciones que llevan por nombre el mismo que se definió para el servicio Rest, por lo que basta con invocar el generador para tener una aplicación en funcionamiento; sin embargo, si se desea programar otras funcionalidades como la autenticación este generador no lo permitirá ya que el código generado no es extensible. Esta forma es ideal cuando se desea tener una aplicación muy sencilla en producción en muy poco tiempo. A continuación un ejemplo de cómo sería la generación de todas las operaciones de una entidad de nombre “Demo” a. Crear getNewRoute "Demo" "demoForm" postNewRoute "Demo" "demoForm" "DemoListR" b. Editar getEditRoute "Demo" "demoForm" postEditRoute "Demo" "demoForm" "DemoListR" c. Eliminar deleteCrudRoute "Demo" "DemoListR" d. Listar 13 Generación de operaciones CRUD para Yesod . listCrudRoute "Demo" "demoFieldOne" Donde: “demoForm” nombre de la forma definida para la entidad. “DemoListR” método a invocar en caso de que la operación de POST se realice. “demoFieldOne” función parámetro a listar. 3.2 Métodos Method Estos métodos no generan funciones que llevan por nombre el mismo que se definió para el servicio Rest, pues no poseen la r mayúscula (R) al final del nombre, el objetivo de éstos es que sean invocados posteriormente por el programador en otro método, permitiéndole adicionar toda la lógica que requiera. A continuación mostramos un ejemplo de la operación crear usando este generador 1. 1. se omiten ejemplos de las demás funciones para facilitar la lectura de este documento a. Crear getNewMethod "Demo2" "demo2Form" postNewMethod "Demo2" "demo2Form" "Demo2ListR" getDemo2NewR :: Handler Html getDemo2NewR = getDemo2New postDemo2NewR :: Handler Html postDemo2NewR = postDemo2New 4. Continuidad La continuidad de este proyecto está orientada a eliminar los principales limitantes del paquete: Generar la forma con tantos parámetros como requiera el usuario. Soporte para el uso de la Internacionalización como se define en Yesod[13] Sería una característica deseable el desacoplar el paquete del Scaffolding[11] de los proyectos por dos motivos, el primero de ellos es por facilidad de uso ya que con ésto el paquete se podría publicar en un repositorio y podría ser usado en cualquier proyecto, además de que permitiría usar el paquete tanto en sitios como en sub sitios. 5. Conclusiones La generación de código para disminuir la complejidad y el tiempo de los desarrollos de software es una constante en crecimiento que viene como parte de todo un conjunto de frameworks y metodología que buscan agilizar tiempos y disminuir recursos. 14 Generación de operaciones CRUD para Yesod . La generación de código que se graba en un archivo ofrece grandes facilidades para extender y personalizar el código, sin embargo supone un problema cuando se requiere realizar un cambio en el modelo ya que en general estos generadores se pueden usar una solo vez y todos los cambios sub siguientes deben ser a mano. EL uso de Haskell y Yesod para desarrollar aplicaciones web ofrece una gran cantidad de ventajas en comparación de otros lenguajes y Frameworks, en particular por la detección de errores –-de tipo y otros--- sobre el código (incluido el código HTML, JavaScript y CSS), con lo que se reduce en gran medida el tiempo de desarrollo y soporte de una aplicación. El uso de este generador facilita el desarrollo de aplicaciones en Yesod, y permite a los programadores tener código operativo en una etapa muy temprana del desarrollo. 6. Referencias [1] Yesod.Helpers.Crud: consultado desde internet el 14/07/2015 https://hackage.haskell.org/package/yesod-0.4.0.3/docs/YesodHelpers-Crud.html [2] Yesod-Crud: consultado desde internet el 14/07/2015 https://github.com/league/yesod-crud [3] Creating a Subsite: consultado desde internet el 14/07/2015 http://www.yesodweb.com/book/creating-a-subsite [4] Template Haskell: consultado desde internet el 16/06/2015 https://wiki.haskell.org/Template_Haskell [5] Quasiquotation: consultado desde internet el 16/06/2015 https://wiki.haskell.org/Quasiquotation [6] Yii Framework en español: Consultado desde internet 21/04/2015 http://yiiframeworkespanol.blogspot.com/2012/06/giigeneracion-automatica-de-codigo.html [7]Synfony 1.0 la guía definitiva capítulo 14 generadores: Consultado desde internet 21/04/2015 http://librosweb.es/libro/symfony_1_0/capitulo_14.html [8] Introducción a Play! Framework: Consultado desde internet 21/04/2015 http://playdoces.appspot.com/documentation/1.2.4/overview [9] Forms: consultado desde internet el 07/06/2015 http://www.yesodweb.com/book/forms [10]Abstract syntax tree consultado desde internet el 17/07/2015 https://en.wikipedia.org/wiki/Abstract_syntax_tree [11] Scaffolding and the Site Template consultado desde internet el 17/07/2015 http://www.yesodweb.com/book/scaffolding-and-thesite-template [12] The MIT License (MIT) consultado desde internet el 22/07/2015 http://opensource.org/licenses/MIT [13] Internationalization consultado desde internet el 17/07/2015 http://www.yesodweb.com/book/internationalization [14] [Haskell-begin] .hi files consultado desde internet el 17/07/2015 https://mail.haskell.org/pipermail/beginners/2008July/000053.html 15