Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

¿Grails + DDD + Eventsourcing + CQRS?

461 views

Published on


Os voy a contar como ha sido la experiencia de nuestro equipo creando una nueva aplicación para un cliente. Os hablaré un poco de las tecnologias, lo que hemos hecho, como lo hemos hecho, lo que nos ha gustado, lo que no nos ha gustado,... Os mostraré código, os enseñaré que cosas de groovy y grails encajan, que otras cosas no nos han encajdo, como ha evolucionado en el tiempo ... Como ha sido la experiencia, que conclusiones hemos sacado, que volveriamos a hacer y que no volveriamos a hacer.

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

¿Grails + DDD + Eventsourcing + CQRS?

  1. 1. Grails DDD EventSourcing CQRS Jorge Franco - Osoco
  2. 2. • Cerca de 20 años desarrollando • Grooscript • 5 años en Osoco, trabajando con Groovy y Java • @jfrancoleza • jorge.franco.leza@gmail.com
  3. 3. Agenda • Groovy & Grails • DDD • Event Sourcing • CQRS • Axon Framework • Nuestra aplicación • Conclusiones
  4. 4. Groovy • Utilizado en Osoco desde los inicios • Lenguaje de la JVM, Apache 2 • Java con esteroides • Dinámico, opcionalmente tipado • Fácil de leer, elegante, conciso • Herencia múltiple? Traits • Testing maravilloso con Spock y Geb
  5. 5. Grails • Mantenido OCI, Apache 2 • Convención sobre configuración • Una capa encima de Spring Boot • Buen ecosistema de plugins • Gorm • Diferentes profiles
  6. 6. Grails tips • Haz muchos tests. • Si vas a integrarte con otras librerías o frameworks, pruébalo antes. • Pon tu código del dominio en src/main/groovy. • Usa las clases Gorm sólo en repositorios. • Si vas a usar @Autowired, asegurarte de que funciona en producción. • Codenarc y Open Clover.
  7. 7. Domain Driven Design • Foco en el dominio y en su lógica • Lenguaje Ubicuo • Bounded contexts, no tiene que ser uno por microservicio • Agregados, entidades, value objects
  8. 8. DDD Tips • No empieces con una fiesta de bounded contexts. • Define bien la paquetería, separación por bounded contexts. • Ten claros cuales son los puntos de entrada a tu dominio. • Pon en común con el equipo que es una invariante, que es una validación, y donde las hacéis. • Diferenciad value objects de entidades. • http://danielwhittaker.me/2015/07/05/are-you-making- these-10-ddd-mistakes/
  9. 9. Event Sourcing • Aplicación tiene estado • Se reciben y se producen eventos • El estado puede cambiar por los eventos • Los eventos se procesan uno tras otro, en secuencia • Podemos volver a un estado de nuestra aplicación, volviendo a aplicar los eventos
  10. 10. ES Tips • Las sesiones de event storming ayudan a identificar los eventos de tu aplicación. • Evita hacer muchas conversiones de objetos o busca una forma fácil de realizarlas. • Prepara tu sistema para volver a cargar los eventos. • Define como otros bounded contexts pueden escuchar tus eventos.
  11. 11. CQRS • Modelo de lectura y modelo de escritura • Query model & Command model • Enriquecer el modelo de lectura para las necesidades de la aplicación (Ej: las vistas) • Información está en varios sitios
  12. 12. CQRS Tips • Los identificadores deben ser únicos y no modificables por el usuario. • Define cuales son las vistas, no guardes en el modelo de lectura más de lo que necesitas. • Puede que tu aplicación falle al guardar en el modelo de lectura y no te enteres.
  13. 13. Axon Framework • Apache 2, Java, http://www.axonframework.org • CQRS and Event Sourcing friendly • Agregado recibe comandos • Los comandos generan eventos • Eventos en el agregado para el modelo de escritura • Eventos para modificar el modelo de lectura • Identificador único para cada agregado • Se lleva bien con spring, es fácil configurar Mongo
  14. 14. class ContractCreateCommand { @TargetAggregateIdentifier String id //Command properties }
  15. 15. @Aggregate class Contract { @AggregateIdentifier String id @CommandHandler Contract(ContractCreateCommand command) { AggregateLifecycle.apply(new ContractCreatedEvent())) } @EventSourcingHandler void onCreate(ContractCreatedEvent event) { //Hacemos cosas en el agregado } }
  16. 16. @EventHandler void onEvent(ClientCreatedEvent clientCreatedEvent) { //Guardamos en el modelo de lectura }
  17. 17. Comando Evento Cambiamos el modelo Evento se persiste Persistimos en el 
 modelo de lectura Consulta Obtenemos la información
 del modelo de lectura
  18. 18. Nuestra aplicación • Gestión de los clientes y sus cuentas de inversión. • Tener claro qué va pasando y quién va haciendo las cosas. • Personas, clientes, contratos, cuentas, gestores, honorarios. • Aplicación grails con axon, datos en postgres, eventos en mongo, gorm, plugin spring security, google oauth, jquery. • Procesado de ficheros de bancos y mucha gestión de documentos. • Despliegue en AWS con Terraform.
  19. 19. BO Grails Mongo Postgres Procesador de ficheros Modelo Común Query
  20. 20. En el BackOffice • Los controladores grails son nuestros puntos de entrada • Lógica de dominio en src/main/groovy • Los dominios tienen puntos de entrada que son llamados desde los controladores • Tenemos entidades Gorm en src/main/groovy y en la librería compartida • Duplicación entre agregados y modelo de lectura, muchas conversiones
  21. 21. Tip Controlador Action Entrada al dominio Caso de Uso Consulta Repositorio Guardar Repositorio
  22. 22. class ContractController { def create(ContractGrailsCommand command) { if (command.hasErrors()) { //devolvemos errores a la vista } Result result = createContractAction.with(command) if (result.hasErrors()) { //devolvemos errores a la vista } else { //all ok! } }
  23. 23. class CreateContractAction { ClientsApplicationService clientsApplicationService Result with(ContractGrailsCommand command) { //Lógica que no sea de dominio //Acceder a diferentes bounded contexts //Convertir los comandos? clientsApplicationService.createContract(command) } }
  24. 24. class CreateContractUseCase { //Cualquier uso de Gorm sólo en los repositorios ContractsRepository contractsRepository Result<String> perform(ContractCommand command) { //Aqui toda la logice de dominio def (errors, contract) = createContractFrom command if (!errors) { //Guardar en el repositorio o repositorios Result.from contractsRepository.create(contract).id } else { Result.fromErrors errors } } }
  25. 25. Conclusiones
  26. 26. DDD nos da muchos beneficios. Separación de la lógica de nuestro dominio del resto. Hay que hablar mucho en el equipo cómo y dónde hacer las cosas, validaciones, servicios, adaptadores, … Evita que la arquitectura te guíe a la hora de construir el modelo
  27. 27. Axon funciona bien. Pruébalo antes de empezar a usarlo. Ten claro lo que hace para aprovecharlo. Centra mucho la lógica en los agregados y los ensucia. Hay que hacer muchas conversiones. Cuidado con las ‘serializaciones’.
  28. 28. Grails encaja a la hora de realizar un backoffice. Es lento y pesado. Cuesta sacar clases Gorm fuera de la aplicación. Los gsp’s son cosa del pasado. Requiere mucha memoria.
  29. 29. Resumen • DDD Sí. Hay que dedicarle tiempo y reuniones. • Grails, sólo para backoffice’s. Si vas a empezar con él sobrecargándolo, mejor piensa en usar otra cosa. • Event sourcing y CQRS, ¿te hace falta?. • Ahora mismo ya no usamos axon, ni eventos ni CQRS. • No empieces una aplicación complicando la vida. • No metas muchas cosas nuevas a la vez.
  30. 30. Q & A
  31. 31. Muchas Gracias!

×