14 de ene. de 2010

GRAILS - El santo grial del desarrollo rápido (Parte I)

Hoy toca algo tecnológico, bueno hoy y algún que otro día más con esta serie.
Algunos diréis que ya era hora, pero el trabajo es lo que tiene, quita tiempo para hacer estas cosas, así que vamos a hacer un pequeño MINI-HOWTO, para poner en marcha una aplicación con este framework de desarrollo rápido, pero primero...
1. ¿Qué es GRAILS?

Grails es un framework para desarrollo rápido de aplicaciones desarrollado sobre Groovy. Grails pretende ser un framework altamente productivo siguiendo dos paradigmas del desarrollo rápido como son "Convention over Configuration" (CoC) y "Don't Repeat Yourself" (DRY), proporciona un entorno de desarrollo estandarizado y oculta la mayoría de los detalles de configuración al desarrollador.
Grails ha sido impulsado principalmente por la empresa G2One, que fue adquirida por SpringSource en noviembre de 2008.
2. ¿De dónde me descargo GRAILS?

Pues fácil y sencillo de su página grails.org, en su zona de descargas está disponible la versión 1.2 del framework.
En su página hay muchos tutoriales y artículos que os servirán de ayuda para dar los primeros pasos. Pero voy a intentar que os saltéis varios de ellos con esta serie de HOW-TOs.
3. Configurar la herramienta:

Lo primero de todo debéis ir a la dirección que os he dicho en el punto 2 y os descargáis el framework, tras esto hay que descomprimirlo en algún lugar que se, yo soy usuario de Linux y de MacOS por lo que usaré la nomenclatura de estos sistemas operativos para referirme a creación de directorios y temas de variables de entorno.

Después de descomprimirlo lo que tenemos que hacer es establecer la variable de entorno $GRAILS_HOME que apunte a la carpeta que acabamos de descomprimir y añadir $GRAILS_HOME/bin al $PATH.
4. Crear el proyecto
Esto es de las cosas que más me gustan de este entorno de desarrollo. Una vez configurada la herramienta, todo lo que tenemos que hacer es ir a una carpeta en la que queramos crear el proyecto, por ejemplo, una carpeta que crearemos para esta serie "grails-howto-series" y ejecutamos el siguiente comando:

grails create-app agenda


Esto os creará la siguiente estructura de carpetas para el proyecto:

grails-howto-series javi$ grails create-app agenda
Welcome to Grails 1.2.0 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/javi/java/grails-1.2.0
Base Directory: /Users/javi/proyectos/grails-howto-series

Resolving dependencies...
Dependencies resolved in 1723ms.

Running script /Users/javi/java/grails-1.2.0/scripts/CreateApp_.groovy
Environment set to development
Warning, target causing name overwriting of name default
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/src
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/src/java
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/src/groovy
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/controllers
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/services
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/domain
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/taglib
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/utils
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/views
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/views/layouts
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/i18n
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/conf
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/test
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/test/unit
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/test/integration
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/scripts
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/web-app
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/web-app/js
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/web-app/css
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/web-app/images
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/web-app/META-INF
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/lib
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/conf/spring
    [mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/conf/hibernate
[propertyfile] Creating new property file: /Users/javi/proyectos/grails-howto-series/agenda/application.properties
...
Created Eclipse project files.
Created Grails Application at /Users/javi/proyectos/grails-howto-series/agenda

Como podéis ver con un solo comando nos hemos creado toda la estructura necesaria para trabajar con el framework.
5. Empecemos con nuestra aplicación de ejemplo.

Una vez que tenemos creada la estructura del proyecto debemos ir a la carpeta raíz del mismo, y a partir de esta podemos comenzar a lanzar comandos de creación de clases de dominio, controladores, servicios, librerías de tag, vistas, filtros, ... todos los comandos que se pueden ejecutar se visualizan lanzando el siguiente comando:

grails help

Para ver la ayuda detallada de algún comando en concreto podéis ejecutar el comando anterior añadiendo el target que queráis, es decir:

grails help create-domain-class

El comando anterior os mostrará la ayuda del target "create-domain-class" que lo que hace es crear una clase groovy que representará una entidad en la base de datos y en nuestra aplicación. Una vez que ya tenemos nuestra estructura creada y hemos jugado un poco con la ayuda del Framework, vamos a crear nuestra primera clase de dominio, para ello ejecutaremos el siguiente comando:

grails create-domain-class Contact

El comando anterior nos dará por consola la siguiente salida:

grails create-domain-class Contacto
Welcome to Grails 1.2.0 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/javi/java/grails-1.2.0

Base Directory: /Users/javi/proyectos/grails-howto-series/agenda

Resolving dependencies...
Dependencies resolved in 3555ms.

Running script /Users/javi/java/grails-1.2.0/scripts/CreateDomainClass.groovy
Environment set to development
WARNING:You have not specified a package. It is good practise to place classesin packages (eg. mycompany.Book). Do you want to continue? (y, n)

Evidentemente le decimos que no, para poder definir esa clase dentro de un paquete y así seguir con las buenas prácticas de desarrollo, lanzaremos por tanto el comando con la siguiente clase de dominio, org.agenda.dominio.Contacto, y obtendremos la siguiente salida por consola:

grails create-domain-class org.agenda.dominio.Contacto
Welcome to Grails 1.2.0 - http://grails.org
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/javi/java/grails-1.2.0
Base Directory: /Users/javi/proyectos/grails-howto-series/agenda

Resolving dependencies...
Dependencies resolved in 1659ms.

Running script /Users/javi/java/grails-1.2.0/scripts/CreateDomainClass.groovy
Environment set to development

[mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/grails-app/domain/org/agenda/dominio
Created DomainClass for Contacto
[mkdir] Created dir: /Users/javi/proyectos/grails-howto-series/agenda/test/unit/org/agenda/dominio
Created Tests for Contacto

Ya tenemos la clase de dominio, ahora la vamos a dar contenido, ya que este comando nos crea una estructura vacía, pero esto lo vemos en el siguiente punto.
6. Dando contenido a nuestras clases de dominio
Para dar contenido a la clase no tenemos más que abrirla con un editor o con un IDE adaptado para el mismo (esto lo veremos en otra parte de la serie), si queréis un editor cualquiera podéis usar gedit (Linux) o TextMate (MacOS).

Una vez abierto le añadimos los siguientes campos:
  • nombre
  • apellidos
  • direccion
  • numero
  • piso
  • puerta
  • codigoPostal
  • poblacion
  • provincia
  • email
  • telefono
  • movil
A estos campos tendremos que tiparles, por lo que usaremos los tipos de datos estandar para cada uno de ellos, a saber, String (nombre,apellidos,direccion,poblacion,provincia, email, telefono y movil), int (numero, piso, codigoPostal) y char (puerta).

La clase Contacto quedará como sigue:

package org.agenda.dominio

class Contacto {
    String nombre
    String apellidos
    String direccion
    int numero
    int piso
    char puerta
    int codigoPostal
    String poblacion
    String provincia
    String email
    String telefono
    String movil

    static constraints = {
    }
}

Una vez definida "totalmente" la clase procederemos a crear los controladores y vistas asociadas a la misma para poder empezar a crear contactos, esto lo vemos en el siguiente punto.
7. Crear los controladores y las vistas

En el punto anterior hemos creado nuestra primera clase de dominio, ahora vamos a crear los controladores y las vistas CRUD asociadas a la misma, para ello el Framework nos ofrece dos opciones, la primera de ellas consiste en usar el comando create-controller (para el controlador) y posteriormente generate-views (para las vistas) o bien, usar un comando que nos genera tanto el controlador como las vistas como es el comando generate-all, en esta primera parte usaremos el segundo por su simplicidad, por tanto lanzaremos el comando siguiente desde consola:

grails generate-all org.agenda.dominio.Contacto

Esto nos dará la siguiente salida por consola:

grails generate-all org.agenda.dominio.Contacto
Welcome to Grails 1.2.0 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to:
/Users/javi/java/grails-1.2.0
Base Directory: /Users/javi/proyectos/grails-howto-series/agenda

Resolving dependencies...
Dependencies resolved in 3924ms.

Running script /javi/java/grails-1.2.0/scripts/GenerateAll.groovy
Environment set to development

[copy] Copied 3 empty directories to 3 empty directories under
/Users/javi/.grails/1.2.0/projects/agenda/resources
[mkdir] Created dir:/Users/javi/proyectos/grails-howto-series/agenda/target/classes
[groovyc] Compiling 2 source files to /Users/javi/proyectos/grails-howto-series/agenda/target/classes
[groovyc] Compiling 8 source files to /Users/javi/proyectos/grails-howto-series/agenda/target/classes
[mkdir] Created dir: /Users/javi/.grails/1.2.0/projects/agenda/resources/grails-app/i18n
[native2ascii] Converting 13 files from /Users/javi/proyectos/grails-howto-series/agenda/grails-app/i18n to /Users/javi/.grails/1.2.0/projects/agenda/resources/grails-app/i18n
[mkdir] Created dir: /Users/javi/.grails/1.2.0/projects/agenda/resources/plugins/hibernate-1.2.0/grails-app/i18n
[native2ascii] Converting 1 file from /Users/javi/.grails/1.2.0/projects/agenda/plugins/hibernate-1.2.0/grails-app/i18n to /Users/javi/.grails/1.2.0/projects/agenda/resources/plugins/hibernate-1.2.0/grails-app/i18n
[copy] Copying 1 file to /Users/javi/proyectos/grails-howto-series/agenda/target/classes
[copy] Copied 2 empty directories to 2 empty directories under /Users/javi/.grails/1.2.0/projects/agenda/resources

Generating views for domain class org.agenda.dominio.Contacto ...
Generating controller for domain class org.agenda.dominio.Contacto ...

Finished generation for domain class org.agenda.dominio.Contacto

Ahora ya estamos listos para ver nuestra primera aplicación en GRAILS funcionando.
8. Ejecutar la aplicación
Ahora lo interesante es probar la aplicación para ello vamos a consola de nuevo y ejecutamos el siguiente comando:

grails run-app

Una vez ejecutado obtendremos esta salida por consola:

grails run-app
Welcome to Grails 1.2.0 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/javi/java/grails-1.2.0
Base Directory: /Users/javi/proyectos/grails-howto-series/agenda

Resolving dependencies...
Dependencies resolved in 3986ms.

Running script /Users/javi/java/grails-1.2.0/scripts/RunApp.groovy 

Environment set to development
[groovyc] Compiling 1 source file to /Users/javi/proyectos/grails-howto-series/agenda/target/classes

Running Grails application..
Server running. Browse to http://localhost:8080/agenda

Abrimos un navegador y vamos a la dirección que nos dice al final de la salida por consola:


Y ahora a probar la aplicación... para esto lo que tenemos que hacer es hacer click sobre el enlace ContactoController y después ya podemos dar de alta contactos, actualizarlos y borrarlos.

Espero que os haya gustado esta primera parte de la serie. En próximas semanas tendremos otras partes, si el tiempo me lo permite...

Salud y a disfrutar!!!