Spring Boot

SpringBoot

Tutorial SpringBoot: Integración con React

Spring Boot y ReactJS: cómo usarlos juntos. Aprende a integrar Spring Boot con ReactJS y desarrolla aplicaciones completas con ejemplos detallados.

React es una biblioteca JavaScript diseñada principalmente para construir interfaces de usuario. Nacido en los laboratorios de Facebook, su enfoque está en permitir la creación de componentes interactivos y reutilizables para aplicaciones web. Estos componentes, que encapsulan tanto la lógica como la vista, se convierten en las unidades básicas con las que los desarrolladores crean interfaces ricas y dinámicas. Uno de los principales beneficios de React es el "Virtual DOM", una representación en memoria del DOM real. Esto permite a React hacer actualizaciones optimizadas, asegurando una alta eficiencia en el rendimiento de las aplicaciones.

Por otro lado, Spring Boot es una extensión del ecosistema Spring que busca simplificar el proceso de configuración y desarrollo de aplicaciones basadas en Spring. A diferencia de las configuraciones tradicionales de Spring que requerían múltiples archivos XML y configuraciones manuales, Spring Boot adopta un enfoque de "convención sobre configuración". Esto significa que Spring Boot viene con configuraciones predeterminadas y listas para usar, facilitando y acelerando el proceso de desarrollo. Además, Spring Boot ofrece una variedad de herramientas y extensiones para desarrollar aplicaciones web, interactuar con bases de datos, y más.

La combinación de React y Spring Boot es particularmente atractiva para desarrolladores y empresas. Mientras React se encarga de proporcionar una experiencia de usuario interactiva y fluida en el front-end, Spring Boot respalda el lado del servidor con un marco robusto, seguro y altamente escalable. La integración de estas dos tecnologías permite a las organizaciones crear aplicaciones web modernas, escalables y de alto rendimiento. Al combinar la modularidad y reactividad de React con la robustez y flexibilidad de Spring Boot, los desarrolladores pueden crear sistemas que no sólo responden rápidamente a las interacciones del usuario, sino que también gestionan eficientemente los recursos y se integran con una variedad de servicios y bases de datos en el back-end.

Configuración del Proyecto:

La integración de React y Spring Boot implica dos dimensiones principales: configurar una aplicación Spring Boot que actuará como el back-end y configurar una aplicación React que será el front-end. Veamos en detalle cómo se configuran ambas partes y cómo se integran:

1. Configuración de Spring Boot:

Para configurar una aplicación Spring Boot:

a. Inicialización: Se puede hacer uso de Spring Initializr, una herramienta web que permite generar la estructura base de un proyecto Spring Boot. Es posible seleccionar las dependencias deseadas, como "Web" para soporte web.

b. Estructura del proyecto: Una vez generado el proyecto, se tendrá una estructura de directorios estándar. En src/main/java se encuentra el código Java del proyecto y src/main/resources para recursos como configuraciones y plantillas.

c. Dependencias: Para una aplicación web básica, se necesita la dependencia spring-boot-starter-web. Si se requiere interactuar con bases de datos, se pueden añadir otras dependencias como spring-boot-starter-data-jpa.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

d. Configuración: Spring Boot utiliza el archivo application.properties o application.yml en src/main/resources para la configuración. Aquí es posible definir propiedades como el puerto del servidor, conexiones a bases de datos, entre otras.

2. Configuración de React:

a. Creación de la aplicación: Utilizar create-react-app, una herramienta CLI que configura automáticamente un proyecto React con buenas prácticas.

npx create-react-app my-react-app

b. Estructura: Este comando generará una carpeta llamada my-react-app con la estructura base de un proyecto React. Contendrá carpetas como public para archivos estáticos y src para el código fuente de la aplicación.

c. Proxy: Si la aplicación React necesita comunicarse con un servidor back-end (en este caso, Spring Boot), es útil configurar un proxy para evitar problemas de CORS durante el desarrollo. En el archivo package.json de la aplicación React, añadir:

"proxy": "http://localhost:8080"

Esto significa que cualquier solicitud que no sea reconocida por el servidor de desarrollo de React se reenviará a http://localhost:8080, la dirección predeterminada de Spring Boot.

3. Integración de React y Spring Boot:

Una estrategia común es servir la aplicación React desde Spring Boot:

a. Construcción de la aplicación React: En la carpeta del proyecto React, ejecutar:

npm run build

Esto generará una versión optimizada de la aplicación en la carpeta build.

b. Mover a Spring Boot: Copiar el contenido de la carpeta build a una nueva carpeta en src/main/resources de la aplicación Spring Boot, generalmente bajo src/main/resources/static.

c. Configuración en Spring Boot: Para que Spring Boot sirva la aplicación React como contenido estático, se puede usar ResourceHandler o simplemente dejar que Spring Boot sirva automáticamente los archivos desde /static.

De esta manera, al ejecutar la aplicación Spring Boot, también se servirá el front-end de React, creando una aplicación web completa e integrada.

Comunicación entre Servidor y Cliente:

Para que una aplicación funcione de manera eficiente y dinámica, la comunicación entre el servidor (en este caso, Spring Boot) y el cliente (React) debe ser fluida y precisa. Esta comunicación se lleva a cabo, en su mayoría, a través de llamadas HTTP utilizando API RESTful. A continuación, se profundizará en este proceso:

1. API RESTful con Spring Boot:

a. Endpoints: Spring Boot facilita la creación de endpoints RESTful mediante el uso de controladores. Estos controladores definen rutas y métodos que gestionan las peticiones HTTP entrantes.

b. Ejemplo básico:

Supongamos que se quiere proporcionar una API que retorne una lista de productos.

@RestController
@RequestMapping("/api/products")
public class ProductController {

    // Esta lista es solo para ilustración. En aplicaciones reales, los datos provendrían de una base de datos.
    private List<Product> products = Arrays.asList(new Product(1, "Laptop"), new Product(2, "Smartphone"));

    @GetMapping
    public ResponseEntity<List<Product>> getAllProducts() {
        return ResponseEntity.ok(products);
    }
}

c. Formato de Respuesta: Por defecto, Spring Boot utiliza Jackson para convertir objetos en JSON. Así, cuando el controlador anterior responde, devuelve la lista de productos en formato JSON.

2. Solicitudes HTTP con React:

a. Fetch API: React no tiene una herramienta incorporada para hacer llamadas HTTP, pero el navegador proporciona la API fetch que se puede usar para este propósito.

b. Ejemplo de solicitud a la API de productos:

fetch("/api/products")
    .then(response => response.json())
    .then(data => {
        console.log("Productos recibidos:", data);
    })
    .catch(error => {
        console.error("Error al obtener los productos:", error);
    });

c. Otras bibliotecas: Si bien fetch es una herramienta poderosa y nativa, existen bibliotecas como Axios que proporcionan una interfaz más rica y manejo de errores más sencillo para realizar llamadas HTTP en aplicaciones React.

3. Gestionar Respuestas y Errores:

a. Spring Boot: Es crucial gestionar y responder adecuadamente a las diferentes situaciones. Por ejemplo, si un recurso no se encuentra, se debe devolver un código de estado 404. Spring Boot facilita esto con ResponseEntity y excepciones.

b. React: Al recibir la respuesta, es vital verificar si la solicitud fue exitosa (por ejemplo, comprobando response.ok en la API fetch). Además, se debe manejar cualquier error que pueda surgir, ya sea un error de red o un error devuelto por el servidor.

4. CORS:

Cuando se desarrollan aplicaciones con cliente y servidor separados, se puede enfrentar un problema de CORS (Cross-Origin Resource Sharing). Es una medida de seguridad implementada por navegadores web, que impide que un dominio web acceda a recursos de otro dominio. Para solucionarlo:

  • Spring Boot: Proporciona soporte para CORS que se puede configurar en los controladores o globalmente en toda la aplicación.
  • React: Durante el desarrollo, se puede establecer un proxy en package.json para evitar problemas de CORS, como se mencionó en la sección anterior.

La comunicación entre el servidor y el cliente es esencial para cualquier aplicación web moderna. A través de una combinación de API RESTful en Spring Boot y solicitudes HTTP en React, es posible crear una interacción dinámica entre el back-end y el front-end, proporcionando una experiencia de usuario fluida y eficiente.

Autenticación y Autorización:

La autenticación y autorización son esenciales para garantizar que solo los usuarios legítimos accedan a recursos específicos y realicen operaciones permitidas. Mientras que la autenticación verifica la identidad del usuario, la autorización decide qué recursos y operaciones están disponibles para ese usuario.

1. Autenticación con Spring Boot:

a. Spring Security: Es la principal herramienta en el ecosistema Spring para manejar la autenticación y autorización. Con la dependencia spring-boot-starter-security, se obtiene una configuración de seguridad básica.

b. Configuración básica: Al incluir Spring Security, se activa una autenticación básica por defecto. Es posible personalizarlo y definir cómo se autenticarán los usuarios y cómo se almacenarán sus credenciales.

c. Ejemplo de configuración:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()  // Por simplicidad, se desactiva CSRF. En un escenario real, es importante manejarlo adecuadamente.
            .authorizeRequests()
                .antMatchers("/api/public/**").permitAll()  // Endpoints públicos
                .anyRequest().authenticated()  // Todos los demás endpoints requieren autenticación
            .and()
            .httpBasic();  // Autenticación básica para fines de ilustración.
    }
}

2. Autorización con Spring Boot:

a. Roles y Privilegios: Con Spring Security, es posible definir roles para los usuarios y asignarles privilegios específicos. Estos roles determinan qué recursos puede acceder un usuario y qué operaciones puede realizar.

b. Ejemplo de Autorización basada en roles:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        ...
        .authorizeRequests()
            .antMatchers("/api/admin/**").hasRole("ADMIN")  // Solo los usuarios con el rol ADMIN pueden acceder.
            .antMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")  // Los usuarios con rol USER o ADMIN pueden acceder.
            ...
}

3. Autenticación y Autorización en React:

a. Manejo de tokens: Una práctica común es utilizar tokens (como JWT) para la autenticación en aplicaciones SPA (Single Page Applications) como las construidas con React. Una vez que el usuario se autentica, el servidor devuelve un token, que luego se almacena en el cliente y se envía con cada solicitud subsiguiente.

b. Ejemplo de autenticación con token:

// Autenticarse y obtener el token
fetch("/api/authenticate", {
    method: "POST",
    body: JSON.stringify({ username: "user", password: "password" }),
    headers: {
        "Content-Type": "application/json"
    }
})
.then(response => response.json())
.then(data => {
    // Almacenar token, por ejemplo, en localStorage
    localStorage.setItem("token", data.token);
})
.catch(error => {
    console.error("Error en la autenticación:", error);
});

c. Uso del token en solicitudes subsiguientes:

// Usar el token en encabezados para futuras solicitudes
const token = localStorage.getItem("token");

fetch("/api/private/resource", {
    headers: {
        "Authorization": `Bearer ${token}`
    }
})
...

4. Rutas Protegidas en React:

Es común proteger ciertas rutas en aplicaciones React para que solo los usuarios autenticados o con roles específicos puedan acceder. Bibliotecas como react-router-dom facilitan la creación de rutas protegidas.

La autenticación y autorización son fundamentales para garantizar la seguridad en aplicaciones web. La combinación de Spring Boot con Spring Security en el back-end y React en el front-end proporciona un conjunto de herramientas robusto para proteger recursos y garantizar que solo los usuarios autorizados puedan acceder y realizar operaciones específicas.

Manejo de Estado y Componentes:

En aplicaciones construidas con React, el estado de un componente es crucial, ya que determina cómo se representa el componente y cómo reacciona a las interacciones del usuario. A continuación, se detallará el manejo del estado en React, así como la importancia de los componentes en la construcción de interfaces de usuario interactivas y dinámicas.

1. Estado en React:

a. ¿Qué es el estado?: El estado en React es un objeto que almacena valores relacionados con un componente. Estos valores pueden cambiar con el tiempo, ya sea debido a interacciones del usuario o a datos que llegan del servidor.

b. setState: Es la forma tradicional de actualizar el estado en componentes basados en clases. Cuando se llama a setState, React planifica una actualización del componente y su subárbol, lo que lleva a un re-renderizado.

class Counter extends React.Component {
    constructor(props) {
        super(props);
        this.state = { count: 0 };
    }

    increment = () => {
        this.setState(prevState => ({
            count: prevState.count + 1
        }));
    }

    render() {
        return (
            <div>
                <p>Count: {this.state.count}</p>
                <button onClick={this.increment}>Increment</button>
            </div>
        );
    }
}

c. Hooks: Con la introducción de los Hooks en React 16.8, el manejo del estado se ha simplificado y se ha hecho más expresivo en componentes funcionales a través del Hook useState.

import { useState } from 'react';

function Counter() {
    const [count, setCount] = useState(0);

    const increment = () => {
        setCount(prevCount => prevCount + 1);
    }

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={increment}>Increment</button>
        </div>
    );
}

2. Componentes en React:

a. Composición: Una de las principales fortalezas de React es la capacidad de componer componentes, lo que significa ensamblar componentes más pequeños para crear componentes más complejos. Esto facilita la reutilización de código y la organización.

b. Props: Los componentes reciben datos a través de props (abreviatura de "propiedades"). Estos son inmutables y permiten que los componentes sean dinámicos y reutilizables.

function Welcome(props) {
    return <h1>Hello, {props.name}</h1>;
}

// Uso del componente
<Welcome name="React" />

c. Componentes controlados: En React, un componente que controla el valor de sus propios elementos de entrada se llama "componente controlado". En estos componentes, el estado de React se convierte en la "fuente única de verdad" para los valores de entrada.

function ControlledInput() {
    const [value, setValue] = useState("");

    const handleChange = event => {
        setValue(event.target.value);
    }

    return (
        <input type="text" value={value} onChange={handleChange} />
    );
}

3. Manejo avanzado del estado:

a. useReducer y Context: Para aplicaciones más grandes, useState puede no ser suficiente. React proporciona otros Hooks, como useReducer para manejar estados más complejos y useContext para compartir estados entre componentes sin necesidad de "prop drilling".

b. Bibliotecas externas: Herramientas como Redux y MobX son soluciones populares para el manejo del estado en aplicaciones React más grandes. Facilitan la organización, miden el flujo de datos y proporcionan utilidades adicionales como middleware.

El manejo del estado y la correcta estructuración de los componentes son fundamentales para desarrollar aplicaciones React eficientes y mantenibles. A través del manejo inteligente del estado y la composición de componentes, se pueden crear interfaces de usuario dinámicas y altamente interactivas que responden a las necesidades del usuario y proporcionan una experiencia de usuario excepcional.

Certifícate en SpringBoot con CertiDevs PLUS

Ejercicios de esta lección Integración con React

Evalúa tus conocimientos de esta lección Integración con React 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 la arquitectura y las responsabilidades separadas de React (front-end) y Spring Boot (back-end).
  2. Aprender a configurar y conectar una aplicación React con un servicio API construido en Spring Boot.
  3. Dominar la comunicación entre el cliente y el servidor, abordando la recuperación, envío y actualización de datos.
  4. Implementar autenticación y autorización, asegurando una interacción segura entre usuario y aplicación.
  5. Profundizar en el manejo del estado en React y cómo se reflejan los cambios en la interfaz basados en las respuestas del back-end.