Microservicios con Spring Boot (1/4)

Introducción a Spring boot 

Comenzamos una serie de cuatro artículos que van a tener como objetivo sacar el máximo partido a la plataforma Spring boot, que nació precisamente con la pretensión de simplificar el trabajo a los desarrolladores, y para ello realiza auto-configuración (convención en vez de configuración) de los componentes. Usa Spring JavaConfig y se puede configurar toda la plataforma sin necesidad de usar XML.

Las aplicaciones de Spring boot son muy sencillas:

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*;

@SpringBootApplication
public class Example {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Example.class, args);
    }
}

Estructura del código  

Ateniéndonos a la estructura hay tres formas de organizar el código de los microservicios:

  1. Proyectos separados
  2. Un solo proyecto multimódulo
  3. Un solo proyecto sin módulos

La elección de uno u otro depende del grado de acoplamiento de los microservicios. Por norma general:

  • Si los microservicios no son dependientes entre ellos se debe de optar por crear proyectos separados, ya que de esta forma se consigue una mayor flexibilidad y pueden diferir en cuanto a configuración sin que afecten a otros microservicios.
  • Si por el contrario, son servicios con dependencias a nivel de lógica de aplicación, es recomendable agruparlos en un proyecto multimódulo, de esta forma nos permite de un vistazo identificar si la modificación de un microservicio puede afectar al resto de los microservicios de los que depende.
  • Por último, Spring boot permite tener varios servicios dentro del mismo proyecto, pudiendo iniciarlos por separado; este caso es adecuado cuando los microservicios tienen dependencia a nivel de lógica de aplicación y también a nivel técnico, ya que van a compartir las mismas librerías y probablemente la misma base de datos.

Para seguir esta serie de artículos se va a proceder a crear en un proyecto especial en Git [podéis descargarlo aquí], donde iremos completando la documentación. En un primer momento, hay que establecer un componente de arquitectura, y luego un proyecto multimódulo para los servicios concretos (que veremos más adelante en la siguiente entrega).

Componente de arquitectura 

Para simplificar la programación se ha creado un componente de arquitectura de forma que sea más sencillo desarrollar los microservicios. Este componente resuelve el tema de la seguridad, la configuración de los websockets, caché de datos, y se puede configurar el accesos al modelo de usuario con JDBC o MongoDB, etc. Esto facilita el desarrollo evitando la repetición de código.

  • Uso del componente de arquitectura:
$ git clone https://git.paradigmadigital.com/git/ArquitecturaMicroServiciosSprinBoot.git arquitecture
$ cd arquitecture
$ gradle bootRun
  • Desarrollo con el componente de arquitectura:

Para crear un servicio nuevo usando la arquitectura creada es tan sencillo como sustituir la anotación @SpringBootApplication por @ParadigmaApplication, y se puede configurar el tipo de acceso para recuperar los datos de usuario. Por defecto está indicado el acceso en memoria, pero para cambiarlo por el acceso a MongoDB hay que indicar @ParadigmaApplication(dataAccessMode = DataAccessMode.MONGO).MicroS2 code4

La seguridad se basa en anotaciones @PreAuthorize y @PostFilter:

@PreAuthorize("hasRole('admin') && @permissions.allowAny('model', 'read')")
@PostFilter("@permissions.allow(filterObject.id, 'model', 'read')")
public List<Model> getAll() {
    ...
}

Está definido un bean en Spring llamado permissions que se encarga de evaluar si se dispone de permisos para una entidad e ID dados. Se puede adaptar la nomenclatura para ajustarla a cada caso concreto, por ejemplo:

@permissions.allow(filterObject.id, 'es.paradigma.inditex.factura', 'imprimir')
@permissions.allow(filterObject.id, 'es.paradigma.inditex.albaran', 'facturar')
@permissions.allow(filterObject.id, 'es.paradigma.inditex.prenda', 'mover')

Para autenticarse tan solo hay que hacer login sobre la url http://localhost:8080/api/v1/login con el body {“demo”, “abcd123”} esto nos devuelve un head “X-AUTH-TOKEN” con el accessToken para poder hacer invocaciones en todos los servicios del proyecto.

Para configurar el acceso a la base de datos que se usa para validar los usuarios se hace uso del archivo arquitectura.yml en donde se guardan todas las propiedades de configuración de la arquitectura común de microservicios.

Hasta aquí esta primera parte en la que hemos intentado conocer cómo funciona Spring boot. En la próxima entrega montaremos un proyecto multimódulo con la herramienta Gradle.

 

Analizamos a fondo Microservicios con Spring Boot en 4 entregas:

Su rol es el de arquitecto software, especializado en tecnologías J2EE. Se trata de seleccionar tecnologías para desarrollos de proyectos desde cero, implementando patrones de software y buenas prácticas de desarrollo . Esto facilita la codificación de las reglas de negocio de forma que los programadores no tengan que preocuparse por la arquitectura que subyace y que ésta les facilite la programación.

Ver toda la actividad de Javier Ledo

Recibe más artículos como este

Recibirás un email por cada nuevo artículo.. Acepto los términos legales

4 comentarios

  1. […] esta segunda entrega de nuestra serie sobre Spring boot nos centraremos en la implementación específica de los distintos microservicios, para ello nos […]

  2. Angel dice:

    Hola, me acabo de descargar el proyecto, he configurado la aplicacion HelloWorldApplication así:

    @ParadigmaApplication(securityMode = SecurityMode.NONE,
    dataAccessMode = DataAccessMode.IN_MEMORY,
    enableAmqpConfig = false,
    enableCommander = false)
    public class HelloWorldApplication

    y al ejecutarlo se produce este error:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘helloWorldController’: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.paradigma.arquitecture.event.EventBus com.paradigma.service.example.HelloWorldController.eventBus; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.paradigma.arquitecture.event.EventBus] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

    ¿Alguna idea de por qué ocurre esto?.

    Gracias.

    • Javier Ledo dice:

      Si la razón es que al indicar enableAmqpConfig=false no se configura el bean EventBus por lo tanto si quieres desactivar esa funcionalidad se debería quitar la inyección de EventBus . De igual forma si se establece la opción enableCommander=false tampoco se configura el bean commander. Esta aplicación de ejemplo usa ambos bean para implementar una arquitectura dirigida por eventos de manera distribuida . En HelloWorldController se inyectan ambos bean:
      @Autowired
      private EventBus eventBus;

      @Autowired
      private Commander commander;

      Si quitas ambos y el método launchEvent() de esa misma clase ya te debería funcionar.
      Me apunto como mejora que el eventBus pueda funcionar en modo local para los casos en los que no hay un rabbitmq disponible .

      Gracias a ti . Cualquier duda o mejora que se te ocurra no dudes en consultarla y te contestaré lo antes posible . Espero que te haya gustado el post.
      Un saludo .

  3. Angel dice:

    Gracias Javier, era justamente la solución por la que había optado.

    Enhorabuena por esta serie de artículos. Esperamos la cuarta entrega :)

    Gracias otra vez.

Escribe un comentario