Spring Boot

SpringBoot

Tutorial SpringBoot: Repositorios reactivos

Spring Boot repositorios reactivos: manejo. Aprende a manejar repositorios reactivos en Spring Boot mediante ejemplos prácticos y detallados.

Los Repositorios Reactivos en Spring Boot, son una parte esencial de la implementación de un sistema de persistencia de datos para una aplicación que sigue el paradigma de programación reactiva.

En el entorno de Spring, estos repositorios son proporcionados por Spring Data y se basan en la Programación Reactiva, un modelo de programación asincrónica que se ocupa de los flujos de datos y la propagación de cambios. Este enfoque es especialmente útil en aplicaciones con un alto volumen de usuarios o datos, ya que permite manejar de manera eficiente grandes cantidades de datos y afrontar situaciones con alta latencia de una forma no bloqueante.

Dentro de Spring Data, existen proyectos para trabajar con bases de datos de forma reactiva como Spring Data R2DBC para bases de datos relacionales y Spring Data MongoDB Reactive para MongoDB.

Por tanto, para poder usar los repositorios reactivos será necesario uno de estos starters, por ejemplo para trabajar con PostgreSQL:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>r2dbc-postgresql</artifactId>
    <scope>runtime</scope>
</dependency>

ReactiveCrudRepository

El ReactiveCrudRepository es una interfaz de Spring Data que define una serie de operaciones para trabajar de manera reactiva con una base de datos. Esta interfaz forma parte de Spring Data y está diseñada para ser utilizada en aplicaciones con Spring Boot. Proporciona operaciones básicas de CRUD (Create, Read, Update, Delete) de manera no bloqueante y asincrónica.

Al igual que otros repositorios de Spring Data, ReactiveCrudRepository trabaja con entidades de dominio y se parametriza con el tipo de la entidad y el tipo de su ID. Los métodos proporcionados por esta interfaz retornan objetos de tipo Mono o Flux, que son proporcionados por la librería Project Reactor.

  • Mono<T>: Representa una secuencia de datos que puede emitir cero o un elemento.
  • Flux<T>: Representa una secuencia de datos que puede emitir cero, uno o muchos elementos.

Aquí hay un ejemplo de cómo se podría usar ReactiveCrudRepository con una entidad Book:

import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import reactor.core.publisher.Mono;

public interface BookRepository extends ReactiveCrudRepository<Book, String> {
  
  Mono<Book> findByTitle(String title);
  
}

En este caso, BookRepository extiende de ReactiveCrudRepository con la entidad Book y su ID de tipo String. Además, se define un método personalizado findByTitle que busca un libro por su título y devuelve un Mono<Book>, que es una secuencia que puede contener el libro buscado o estar vacía si no se encuentra.

Los métodos que se obtienen al extender ReactiveCrudRepository incluyen:

  • save(S entity): Guarda una entidad y retorna un Mono con la entidad guardada.
  • findAll(): Encuentra todas las entidades y retorna un Flux con las entidades encontradas.
  • findById(ID id): Busca una entidad por su ID y retorna un Mono con la entidad encontrada.
  • delete(S entity): Borra una entidad y retorna un Mono<Void> cuando se ha completado la operación.

Estos métodos permiten realizar operaciones de base de datos de forma reactiva y no bloqueante, lo que puede mejorar el rendimiento y la escalabilidad de las aplicaciones en escenarios con alta latencia o gran cantidad de usuarios.

Operadores Reactivos

Los Operadores Reactivos son funciones que permiten manipular las secuencias de datos en la programación reactiva. Estos operadores permiten transformar, filtrar, combinar, crear, y de muchas otras formas manipular los flujos de datos de los objetos Flux y Mono en Project Reactor, una librería de programación reactiva en Java usada por Spring.

Aquí hay algunos ejemplos de operadores reactivos y cómo se utilizan:

Transformación

Los operadores de transformación modifican los elementos de una secuencia. Por ejemplo, el operador map aplica una función a cada elemento en el flujo:

Flux<Integer> flux = Flux.just(1, 2, 3)
  .map(i -> i * 2);  // transforma el flujo a 2, 4, 6

Filtro

Los operadores de filtro eliminan elementos del flujo basándose en algún criterio. El operador filter permite pasar sólo los elementos que satisfacen una condición dada:

Flux<Integer> flux = Flux.just(1, 2, 3, 4, 5)
  .filter(i -> i % 2 == 0);  // filtra el flujo a 2, 4

Combinación

Los operadores de combinación unen múltiples flujos en uno solo. Por ejemplo, el operador zip combina los elementos de varios flujos en un flujo de tuplas:

Flux<Integer> flux1 = Flux.just(1, 2, 3);
Flux<String> flux2 = Flux.just("a", "b", "c");

Flux<Tuple2<Integer, String>> zipped = Flux.zip(flux1, flux2);  // combina los flujos a (1,"a"), (2,"b"), (3,"c")

Creación

Los operadores de creación generan un flujo a partir de diversas fuentes de datos. Por ejemplo, el operador just crea un flujo a partir de uno o más elementos:

Flux<Integer> flux = Flux.just(1, 2, 3);  // crea un flujo con los elementos 1, 2, 3

Error

Los operadores de error manejan los errores que pueden ocurrir durante el procesamiento de un flujo. Por ejemplo, el operador onErrorReturn permite especificar un valor de retorno cuando ocurre un error:

Flux<Integer> flux = Flux.just(1, 2, 3)
  .map(i -> {
    if (i == 2) {
      throw new RuntimeException("Error!");
    }
    return i;
  })
  .onErrorReturn(-1);  // en caso de error retorna el flujo con el valor -1

Los operadores reactivos son fundamentales para manejar los flujos de datos en la programación reactiva. Permiten realizar operaciones complejas con flujos de datos de manera declarativa y no bloqueante, mejorando la eficiencia y la escalabilidad de las aplicaciones.

Integración con Project Reactor

Project Reactor es una librería para la programación reactiva en el ecosistema de Spring. Proporciona abstracciones para Java que manejan los flujos de datos de forma no bloqueante y respaldan tanto operaciones síncronas como asincrónicas.

Los dos tipos principales que proporciona Project Reactor son Mono y Flux:

  • Mono<T>: Representa un flujo de datos que emitirá 0 o 1 elemento. Se puede usar cuando se espera que una operación devuelva un solo resultado o ninguno, por ejemplo, al buscar un solo registro en una base de datos.

  • Flux<T>: Representa una secuencia de 0 a N elementos. Se puede usar cuando se espera que una operación devuelva múltiples resultados, por ejemplo, al realizar una consulta que devuelve varios registros de una base de datos.

Estos tipos son fundamentales en los repositorios reactivos de Spring Data, que los utilizan para representar los resultados de las consultas de base de datos. Por ejemplo, en un ReactiveCrudRepository, los métodos findById y findAll devolverán un Mono y un Flux respectivamente.

Aquí hay un ejemplo de cómo se podrían utilizar estos tipos en un ReactiveCrudRepository:

public interface UserRepository extends ReactiveCrudRepository<User, String> {
  
  Mono<User> findByUsername(String username);
  
  Flux<User> findAllByAge(int age);
  
}

En este ejemplo, findByUsername devolverá un Mono<User> porque se espera que la búsqueda por nombre de usuario devuelva un solo usuario o ninguno. Por otro lado, findAllByAge devolverá un Flux<User> porque la búsqueda por edad podría devolver varios usuarios.

Los tipos Mono y Flux proporcionan una amplia gama de operadores que permiten transformar, filtrar, combinar y realizar muchas otras operaciones en los flujos de datos. Por ejemplo:

Flux<User> users = userRepository.findAllByAge(20);
Mono<User> user = userRepository.findByUsername("john");

users.map(User::getUsername) // Transforma el flujo de User a un flujo de nombres de usuario.
  .subscribe(System.out::println); // Imprime cada nombre de usuario.

user.map(User::getUsername) // Transforma el Mono<User> a un Mono<String> con el nombre de usuario.
  .subscribe(System.out::println); // Imprime el nombre de usuario.

La integración con Project Reactor permite a los repositorios reactivos de Spring Data proporcionar una API no bloqueante para las operaciones de base de datos, permitiendo un uso más eficiente de los recursos del sistema en aplicaciones con alta carga o latencia.

Conclusión

Los repositorios reactivos en Spring Boot representan una alternativa importante al enfoque tradicional de bloqueo en las operaciones de base de datos. Permiten a las aplicaciones manejar un gran número de solicitudes concurrentes de manera más eficiente al utilizar los recursos del sistema de manera no bloqueante.

La principal ventaja de utilizar repositorios reactivos es que permiten a las aplicaciones seguir trabajando en otras tareas mientras esperan a que las operaciones de base de datos se completen. Esto puede llevar a una mayor utilización de los recursos del sistema y una mayor capacidad de respuesta, especialmente en escenarios de alta latencia o con un gran número de usuarios concurrentes.

Además, los repositorios reactivos se integran con el Project Reactor de Spring, proporcionando una API rica para manipular los flujos de datos de manera declarativa. Los tipos Mono y Flux y los operadores reactivos permiten transformar, filtrar, combinar y realizar muchas otras operaciones en los flujos de datos.

Sin embargo, la programación reactiva también tiene sus desafíos. Puede ser más difícil de entender y depurar debido a su naturaleza asincrónica y no bloqueante. También puede requerir cambios significativos en la arquitectura de una aplicación para aprovechar sus beneficios.

Certifícate en SpringBoot con CertiDevs PLUS

Ejercicios de esta lección Repositorios reactivos

Evalúa tus conocimientos de esta lección Repositorios reactivos con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Web y Test Starters

Spring Boot
Puzzle

Entidades JPA

Spring Boot
Test

Repositorios reactivos

Spring Boot
Test

Inserción de datos

Spring Boot
Test

Borrar datos de base de datos

Spring Boot
Test

Controladores Spring MVC

Spring Boot
Código

Backend API REST con Spring Boot

Spring Boot
Proyecto

Operadores Reactivos

Spring Boot
Puzzle

Controladores Spring REST

Spring Boot
Código

Uso de Spring con Thymeleaf

Spring Boot
Puzzle

Crear entidades JPA

Spring Boot
Código

Registro de usuarios

Spring Boot
Test

CRUD y JPA Repository

Spring Boot
Puzzle

Anotaciones y mapeo en JPA

Spring Boot
Puzzle

Integración con Vue

Spring Boot
Test

Consultas JPQL con @Query en Spring Data JPA

Spring Boot
Test

Open API y cómo agregarlo en Spring Boot

Spring Boot
Puzzle

Uso de Controladores REST

Spring Boot
Puzzle

API Specification

Spring Boot
Puzzle

Inyección de dependencias

Spring Boot
Test

Introducción a Spring Boot

Spring Boot
Test

Consultas JPQL con @Query en Spring Data JPA

Spring Boot
Puzzle

API Query By Example (QBE)

Spring Boot
Puzzle

Inyección de dependencias

Spring Boot
Código

Vista en Spring MVC con Thymeleaf

Spring Boot
Test

Servicios en Spring

Spring Boot
Código

Configuración de Vue

Spring Boot
Puzzle

Integración con Angular

Spring Boot
Test

API Query By Example (QBE)

Spring Boot
Test

API Specification

Spring Boot
Test

Controladores MVC

Spring Boot
Test

Métodos find en repositorios

Spring Boot
Test

Repositorios Spring Data

Spring Boot
Test

Inyección de dependencias

Spring Boot
Puzzle

Data JPA y Mail Starters

Spring Boot
Test

Configuración de Angular

Spring Boot
Puzzle

Controladores Spring REST

Spring Boot
Test

Configuración de Controladores MVC

Spring Boot
Puzzle

Asociaciones de entidades JPA

Spring Boot
Código

Actualizar datos de base de datos

Spring Boot
Test

Identificadores y relaciones JPA

Spring Boot
Puzzle

Verificar token JWT en peticiones

Spring Boot
Test

Login de usuarios

Spring Boot
Test

Integración con React

Spring Boot
Test

Configuración de React

Spring Boot
Puzzle

Asociaciones en JPA

Spring Boot
Test

Consultas JPQL

Spring Boot
Código

Todas las lecciones de SpringBoot

Accede a todas las lecciones de SpringBoot y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Spring Boot

Spring Boot

Introducción Y Entorno

Spring Boot Starters

Spring Boot

Introducción Y Entorno

Inyección De Dependencias

Spring Boot

Introducción Y Entorno

Controladores Spring Mvc

Spring Boot

Spring Web

Vista En Spring Mvc Con Thymeleaf

Spring Boot

Spring Web

Controladores Spring Rest

Spring Boot

Spring Web

Open Api Y Cómo Agregarlo En Spring Boot

Spring Boot

Spring Web

Servicios En Spring

Spring Boot

Spring Web

Crear Entidades Jpa

Spring Boot

Persistencia Con Spring Data

Asociaciones De Entidades Jpa

Spring Boot

Persistencia Con Spring Data

Repositorios Spring Data

Spring Boot

Persistencia Con Spring Data

Métodos Find En Repositorios

Spring Boot

Persistencia Con Spring Data

Inserción De Datos

Spring Boot

Persistencia Con Spring Data

Actualizar Datos De Base De Datos

Spring Boot

Persistencia Con Spring Data

Borrar Datos De Base De Datos

Spring Boot

Persistencia Con Spring Data

Consultas Jpql Con @Query En Spring Data Jpa

Spring Boot

Persistencia Con Spring Data

Api Query By Example (Qbe)

Spring Boot

Persistencia Con Spring Data

Repositorios Reactivos

Spring Boot

Persistencia Con Spring Data

Api Specification

Spring Boot

Persistencia Con Spring Data

Integración Con React

Spring Boot

Integración Frontend

Integración Con Vue

Spring Boot

Integración Frontend

Integración Con Angular

Spring Boot

Integración Frontend

Registro De Usuarios

Spring Boot

Seguridad Con Spring Security

Login De Usuarios

Spring Boot

Seguridad Con Spring Security

Verificar Token Jwt En Peticiones

Spring Boot

Seguridad Con Spring Security

En esta lección

Objetivos de aprendizaje de esta lección

  1. Comprender qué son los repositorios reactivos y cuándo utilizarlos en el desarrollo de aplicaciones.
  2. Aprender a utilizar la interfaz ReactiveCrudRepository para implementar operaciones CRUD reactivas.
  3. Conocer los operadores reactivos y cómo se utilizan para manipular flujos de datos en la programación reactiva.
  4. Entender la integración de los repositorios reactivos con Project Reactor y cómo utilizar los tipos Mono y Flux.
  5. Evaluar los beneficios y desafíos de la programación reactiva y cómo puede mejorar el rendimiento y la escalabilidad de las aplicaciones.