Desarrollo Ágil de Aplicaciones Web con Grails Framework. Caso ...
Greach 2013 - Todo lo que me hubiera gustado saber cuando empecé a desarrollar con grails
-
Upload
ivan-lopez -
Category
Technology
-
view
4.681 -
download
1
description
Transcript of Greach 2013 - Todo lo que me hubiera gustado saber cuando empecé a desarrollar con grails
Todo lo que me hubiera gustado saber cuando empecé a desarrollar con Grails
Iván López - @ilopmarIván López - @ilopmar “Oh finally, I can feel the power”
● Iván López Martín @ilopmar
● Uso Grails/Groovy desde hace 3 años y Java desde hace muchos más.
● Creador de www.bokzuy.com
● Creador de plugins de grails (ducksboard-api y slug-generator)
● 3º en hackaton Grails48 con confspot.com
● Geek, Padre, Desarrollador, Sysadmin, Linuxero y Pro-Software libre
● Trabajo en Kaleidos
¿Quién soy?
Agenda
Si, pero esto de qué va...
Google Stack Overflow Grails-user/Blogs
Noches sin dormir
Trabajo efectivo
Tiem
po
...de esto!
Google Stack Overflow Grails-user/ Blogs
Noches sin dormir
Trabajo efectivo
Porno
Tiem
po
Domain
● Poner toda la lógica relacionada con el objeto que estamos tratando en su clase de dominio.
● Modelos anémicos vs Modelos Ricos.
● Usar namedQueries.
● No utilizar booleanos nullables: crear enums.
● Validadores personalizados en constraints.
Domain
Controllers
● No poner lógica de negocio en controllers.
● Responsabilidades: - Recibir una petición. - Verificar los parámetros. - Llamar a un servicio (o varios) para obtener los datos. - Renderizar una respuesta (html, xml, json) o redirect.
● CommandObjects para data binding complejo.
● Los CommandObjects pueden heredar de otros.
Controllers
Servicios
● Lógica de negocio no implementada en domain.
● Si no es necesaria transaccionalidad static transactional = false
● Si es transaccional, no utilizar flush:true
● Tipos de los parámetros en los métodos y en valor de retorno.
● No closures porque no hay transaccionalidad.
● src/groovy
Servicios
Vistas
● KISS.
● Templates para las partes comunes de las páginas.
● Templates para elementos que se repitan.
● No intentar reutilizar templates con if's y pequeños hacks porque acaban siendo inmantenibles.
● No inyectar servicios: usar TagLib, Controller o Modelos Ricos.
Vistas
TagLibs
● Namespace específico para el proyecto o pluginstatic namespace = 'myNs' --> <myNs:myMethod />
● Cálculos relativamente complejos para listas con renderización común.
● Generar respuesta HTML con template.
● Un TagLib se puede llamar desde un controller con myNs.myMethod
TagLibs
I18N
● Política de claves para messages.properties.Por ejemplo: pantalla.módulo.objeto-del-dominio.atributo
● Agrupar las claves por pantallas.
● ¡Respetar la política definida!
● ¡En serio! :-)
● Plurales:
my.msg = {0,choice,0#No hay resultados|1#Sólo un resultado|1<{0} resultados}
<g:message code='my.msg' args="[numResults]" />
I18N
URL Mappings
● Usar namedUrls.
● Filtrar los métodos aceptados (GET, POST,...) en url y no en static allowedMethods: 404 en lugar de 405.
name oneProposal: "/proposal/$proposalId" { controller = 'proposal'; action = [GET:'showProposal', POST:'updateProposal']}
<g:link mapping="oneProposal" params="[proposalId:entry.id]">
redirect mapping:'oneProposal',params:proposalId:proposal.id]
url = grailsLinkGenerator.link(absolute:true, mapping:'oneProposal', params:[proposalId:timeline.id])
URL Mappings
Tests
● Hay que hacer tests, obvio ¿no? ;-)
● Spock.
● Servidor de Integración Continua: p.e. Jenkins.
● Plugins Fixtures y Build Test Data.
● Mejor Test Unitarios son más rápidos pero hay que mockear más.
● Usar BD final y no H2 en Integración.
● Vistas difíciles de testear, aproximación en Integración con controllers que hacen render template.
Tests
Configuración
● Utilizar correctamente los entornos en Config.groovy.● No subir a control de versiones archivos con configuración personal (usuarios, contraseñas,...). DataSource.groovy DataSource.groovy.sample→
● Crear archivo properties (aunque esté vacío inicialmente) para cambiar parámetros generar un nuevo war (p.e: producción).En Config.groovy:grails.config.locations = ["classpath:myconfig.properties"]
● No ejecutar grails install-plugin xxxxx, definir la dependencia en BuildConfig.groovy
Configuración
Logs
● Es necesario que haya logs en la aplicación.
● No hay nada más frustante que una aplicación en producción en la que falla y no tenemos información en los logs para analizar el error.
● println está prohibido. Mejor log.debug, log.info,...
● Política de severidad de los mensajes y respetarla.
● Configurar por entorno el nivel mínimo de log mostrado.
Logs
Apps complejas
● La clave es Modularizar.
● El core en plugin común con clases de dominio y servicios comunes.
● Una aplicación diferente por “funcionalidad”: - Página web - Página para dispositivos móviles - API
● En estas aplicaciones importar el plugin inline.
Apps complejas (I)
● Ventajas: - Distribuir la carga. - Separación clara de funcionalidades.● Inconvenientes: - Más consumo de memoria - Aplicación más compleja - Despliegues más complejos - Ejecución de tests en varios proyectos ● ¡Aún así merece la pena!
Apps complejas (II)
Miscelánea
● Relaciones xxx-to-many “automáticas” o “a mano”.● Filtrar siempre que sea posible en la base de datos:def data = User.list().find { it.name == 'pepe' } // No def data = User.findAllByName('pepe') // Sídef data = User.findAllByName('pepe', [cache:true])
● Igual para obtener sólo el primer elemento, el último, los 3 últimos,...def data = (Company.list() as List).first() // Nodef data = Company.withCriteria { // Sí order('date', 'desc') maxResult(1) cache true // si queremos cachear}
● Métodos específicos que hagan con count en la bd en lugar de list.size()
Rendimiento
Scaffolding
““Un gran poder conlleva una gran Un gran poder conlleva una gran responsabilidad”responsabilidad”
http://lopezivan.blogspot.comhttp://lopezivan.blogspot.com
@ilopmar@ilopmar
https://github.com/lmivanhttps://github.com/lmivan
Iván López MartínIván López Martín
Benjamin Parker (Tío Ben)Benjamin Parker (Tío Ben)
[email protected]@gmail.com