Nueva visita a Herramientas para un proyecto Java

Escrito por el , actualizado el .
java opinion planeta-codigo programacion
Enlace permanente Comentarios

Las tecnologías para desarrollar una aplicación son un medio para resolver las necesidades del negocio o un cliente, no un fin. Pero esto no quiere decir que la elección sea trivial o poco importante, realizar las elecciones adecuadas según lo requisitos puede evitar complicaciones en un futuro. Para un proyecto basado en la plataforma Java esta es mi selección de herramientas de las que conozco.

Java

Hace 5 años escribí un artículo comentando que tecnologías elegiría para un proyecto Java si tuviese posibilidad. Al ritmo que avanza la tecnología cuatro años es un tiempo bastante largo, también es un tiempo en el que he podido aprender y añadir a mi «caja de herramientas» nuevas opciones que después de evaluarlas me han gustado. En este artículo haré una nueva visita al artículo anterior y comentaré algunas nuevas herramientas.

Lenguaje de programación

Como lenguaje de programación seguiría usando Java, en mi caso es el lenguaje que más conozco y sigue siendo una de las opciones más válidas. Pero con la salida de una nueva versión usaría Java 8. La publicación de Java 8 incorporando varias novedades importantes han mejorado varios aspectos de este lenguaje, por mencionar los más relevantes están la incorporación de lambdas que proporciona una cierta forma de programación funcional, también destaca los streams que permite describir los algoritmos que procesan datos de una forma más expresiva y legible además de aprovechar mejor los procesadores multinúcleo, métodos por defecto en interfaces que permite mantener compatibilidad hacia atrás (aunque esto interesa más a los desarrolladores que hacen APIs para que sean usadas por terceras partes), una nueva API para el manejo de fechas eliminando una de las críticas de versiones anteriores y algunas cosas más. El futuro con Java 9 es prometedor si presenta la interesante modularidad.

Persistencia en base de datos

Las librerías más populares de persistencia en Java son Hibernate aunque para algunos casos usaría o como complemento jOOQ, Spring Data ofrece varias utilidades para facilitar crear las clases repositorio usando Hibernate.

jOOQ es una librería que no tienen tanta magia como Hibernate que en muchas ocasiones produce errores complicados de resolver y no tenemos tanto control de lo que hace, por otro lado jOOQ devuelve a la base de datos y al lenguaje SQL la relevancia que con Hibernate queda abstraída con el mapeado del modelo de datos a objetos y el lenguaje HQL. jOOQ permite construir las sentencias SQL de forma programática con lo que el compilador nos indicará errores de compilación y nos validará los tipos que usemos, ambas cosas son importantes cuando hacemos un refactor en alguna parte de la aplicación. En el artículo alternativa a Hibernate y ejemplo jOOQ entro en más detalles.

Al persistir datos si es necesario realizar auditoría de datos dos posibilidades son Envers específica para Hibernate y Javers usable con cualquier librería de persistencia. Permiten guarda los típicos campos fecha creación, usuario creación, fecha modificación y última modificación asi como mantener un histórico completo de todos los cambios realizados a una entidad.

Modificaciones de la base de datos

En un proyecto de larga duración y en el que se realicen mejoras probablemente necesitaremos modificar el modelo de la base de datos. Empleando la herramienta Liquibase podremos automatizar la actualización del esquema de la base de datos ya necesitemos añadir campos, cambiarlos de nombre, eliminarlos, crear o eliminar tablas, insertar, eliminar o actualizar datos. Estas actualizaciones de la base de datos se indican en un archivo que podemos guardar en nuestro repositorio de control de versiones de forma que podamos ver y reproducir los cambios que se han hecho a la base de datos a lo largo del tiempo.

Pruebas

Para pruebas unitarias dos buenas posibilidades son JUnit, Spock y Geb. Spock permite realizar los teses unitarias con un DSL bastante descriptivo que facilita la lectura posteriormente de la prueba, sin embargo, JUnit ofrece las mismas ventajas para los teses que el para el código de la aplicación al usar Java. Por otro lado Geb permite automatizar las pruebas de las aplicaciones web proporcionando facilidades, se puede integrar con Spock.

Otra herramienta muy útil es Testcontainers que permite hacer pruebas de integración usando el mismo software de producción como puede ser una base de datos MySQL o PostgreSQL en vez de una base de datos en memoria.

Cliente

En el lado cliente de una aplicación web usaría la combinación de varias tecnologías, jQuery para acceder y manipular el DOM de la página web, RequireJS para cargar los archivos necesarios en la página y evitar la polución del ámbito global JavaScript.

Si la aplicación tiene una carga importante en el lado cliente evaluaría usar TypeScript como lenguaje por ser un compilado con sus ventajas en bases de código grandes, Webpack para gestionar los recursos, empaquetarlos y realizar transformaciones como alternativa a RequireJS y React para crear componentes en el lado cliente. Jest o Jasmine para hacer pruebas unitarias en JavaScript.

Framework web

Para el desarrollo de una página o aplicación web seguiría usando Apache Tapestry por la productividad y alta reutilización que se puede conseguir, también por la flexibilidad, extensibilidad y adaptabilidad del framework si necesita recursos de cliente añadiendo dependencias con Webjars. Descargando el libro PlugIn Tapesty puedes conocer muchos más detalles.

Si se tratase de una aplicación REST evaluaría [Spring Boot][springboot] o GraphQL para proporcionar la interfaz exterior de los microservicios y quizá evaluaría Apache Thrift o gRPC para consumirlos internamente, Thrift permite acceder a la API de una forma programática más sencillamente que consumir una interfaz REST o GraphQL cruda.

La tendencia actual es desarrollar microservicios y esto en las aplicaciones web supone que sean capaces de ofrecer su servicio por si mismas no usando un servidor de aplicaciones que hay que instalar previamente simplificando el despliegue a los administradores de sistemas, esto también se puede conseguir en parte usando Docker. En vez de usar un Tomcat tradicional podemos usar la versión embebible o Spring Boot.

Base de datos

Para una base de datos relacional en vez de MySQL usaría PostgreSQL. PostgreSQL posee numerosas opciones avanzadas y es una de las bases de datos libres más reconocidas. El futuro de MySQL con Oracle y su escisión en MariaDB es más incierto además de no poseer algunas características que PostgreSQL sí.

Dependiendo del causística de la aplicación otras opciones complementarias son Redis y MongoDB, una base de datos clave-valor, una base de datos de documentos y en caso de tener que hacer búsquedas de texto completo con Elasticsearch.

Entorno de desarrollo

Para el entorno de desarrollo o devbox usaría Docker y Compose que permiten disponer de un entorno más parecido al entorno de producción y en menos tiempo que instalando todo lo necesario en la máquina física. También podemos usar Docker para el entorno de producción. Para automatizar la tareas de configuración o despliegue usaría Ansible ya que al contrario de otras opciones no requiere instalar un agente en las máquinas a administrar, con un acceso SSH es suficiente.

Hospedaje

En cuanto al alojamiento para la aplicación la nube es otra tendencia por su flexibilidad. La nube de Amazon proporciona muchos servicios que pueden sernos útiles sin embargo si nuestra aplicación no los necesita y no es demasiado complicada podemos optar por otras opciones más baratas. Dos opciones más baratas son Linode o Digital Ocean con las que por unos 5 o 10 € al mes podemos disponer de una máquina con 1 GIB de RAM, unos 30 GiB de discos SSD y una amplia transferencia de datos entrantes y salientes.

Aún usando un servicio en la nube para no encadenarse a uno determinado y disponer un centro de datos están Consul como sistema de registro, descubrimiento, gestión de configuración y conexión entre servicios, Vault para usar seguridad como servicio, Nomad como orquestador de las aplicaciones con posibilidad de hacer despliegues blue/greeen o canary asi com volver a una versión anterior fácilmente y Terraform para aprovisionar el entorno en la nube independiente del proveedor y haciendo que la infraestructura este bajo el control de versiones al usar infraestructura como código.

Otras

Otras funcionalidades que necesita algunas aplicaciones son:

De algunas de estas herramientas he escrito de forma individualizada.

Hay otras herramientas aún pasado este tiempo seguiría usando como Git para el control de versiones, GitLab como plataforma para desarrollo que incluye repositorio de git, gestión de peticiones e integración continua además de otras funcionalidades en una única herramienta. SDKMAN para gestionar las versiones de librerías Java en el entorno de desarrollo, Gradle como herramienta de construcción, GNU/Linux tanto para desarrollar como para el servidor en el que desplegar la aplicación, IntelliJ como IDE para editar código Java o Visual Studio Code para editar archivos no Java.

Usar herramientas adecuadas para un proyecto es importante aunque independientemente de las herramientas también es importante la metodología, Domain Divern Design o DDD propone numerosas pautas para organizar y modelar aplicaciones complejas con reglas de negocio de mofo que las diferentes partes estén desacopladas y el mantenimiento sea más sencillo. Los patrones de diseño aplicados de forma adecuada simplifican enormemente el código.

Para cada un de estas herramientas en muchos casos tendremos varias alternativas similares para elegir, a veces elegir una u otra es algo subjetivo. Estas herramientas en muchos casos son de lo mejor que hay disponible pero perfectamente se pueden usar alternativas similares.

¿Cuales serán las herramientas que formarán el «estado del arte» dentro de otros cuatro años? ¿Cuales sobrevivirán y cuales perecerán en el camino? ¡Apasionante!


Comparte el artículo: