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.
Aprende SpringBoot GRATIS y certifícateReact 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.
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.
API Query By Example (QBE)
Identificadores y relaciones JPA
Borrar datos de base de datos
Web y Test Starters
Métodos find en repositorios
Controladores Spring MVC
Inserción de datos
CRUD Customers Spring MVC + Spring Data JPA
Backend API REST con Spring Boot
Controladores Spring REST
Uso de Spring con Thymeleaf
API Specification
Registro de usuarios
Crear entidades JPA
Asociaciones en JPA
Asociaciones de entidades JPA
Integración con Vue
Consultas JPQL
Open API y cómo agregarlo en Spring Boot
Uso de Controladores REST
Repositorios reactivos
Inyección de dependencias
Introducción a Spring Boot
CRUD y JPA Repository
Inyección de dependencias
Vista en Spring MVC con Thymeleaf
Servicios en Spring
Operadores Reactivos
Configuración de Vue
Entidades JPA
Integración con Angular
API Specification
API Query By Example (QBE)
Controladores MVC
Anotaciones y mapeo en JPA
Consultas JPQL con @Query en Spring Data JPA
Repositorios Spring Data
Inyección de dependencias
Data JPA y Mail Starters
Configuración de Angular
Controladores Spring REST
Configuración de Controladores MVC
Consultas JPQL con @Query en Spring Data JPA
Actualizar datos de base de datos
Verificar token JWT en peticiones
Login de usuarios
Integración con React
Configuración de React
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
Introducción Y Entorno
Spring Boot Starters
Introducción Y Entorno
Inyección De Dependencias
Introducción Y Entorno
Controladores Spring Mvc
Spring Web
Vista En Spring Mvc Con Thymeleaf
Spring Web
Controladores Spring Rest
Spring Web
Open Api Y Cómo Agregarlo En Spring Boot
Spring Web
Servicios En Spring
Spring Web
Clientes Resttemplate Y Restclient
Spring Web
Rxjava En Spring Web
Spring Web
Crear Entidades Jpa
Persistencia Spring Data
Asociaciones De Entidades Jpa
Persistencia Spring Data
Repositorios Spring Data
Persistencia Spring Data
Métodos Find En Repositorios
Persistencia Spring Data
Inserción De Datos
Persistencia Spring Data
Actualizar Datos De Base De Datos
Persistencia Spring Data
Borrar Datos De Base De Datos
Persistencia Spring Data
Consultas Jpql Con @Query En Spring Data Jpa
Persistencia Spring Data
Api Query By Example (Qbe)
Persistencia Spring Data
Api Specification
Persistencia Spring Data
Repositorios Reactivos
Persistencia Spring Data
Introducción E Instalación De Apache Kafka
Mensajería Asíncrona
Crear Proyecto Con Apache Kafka
Mensajería Asíncrona
Creación De Producers
Mensajería Asíncrona
Creación De Consumers
Mensajería Asíncrona
Kafka Streams En Spring Boot
Mensajería Asíncrona
Introducción A Spring Webflux
Reactividad Webflux
Spring Data R2dbc
Reactividad Webflux
Controlador Rest Reactivo Basado En Anotaciones
Reactividad Webflux
Controlador Rest Reactivo Funcional
Reactividad Webflux
Operadores Reactivos Básicos
Reactividad Webflux
Operadores Reactivos Avanzados
Reactividad Webflux
Cliente Reactivo Webclient
Reactividad Webflux
Introducción A Spring Security
Seguridad Con Spring Security
Seguridad Basada En Formulario En Mvc Con Thymeleaf
Seguridad Con Spring Security
Registro De Usuarios
Seguridad Con Spring Security
Login De Usuarios
Seguridad Con Spring Security
Verificar Token Jwt En Peticiones
Seguridad Con Spring Security
Seguridad Jwt En Api Rest Spring Web
Seguridad Con Spring Security
Seguridad Jwt En Api Rest Reactiva Spring Webflux
Seguridad Con Spring Security
Autenticación Y Autorización Con Anotaciones
Seguridad Con Spring Security
Testing Unitario De Componentes Y Servicios
Testing Con Spring Test
Testing De Repositorios Spring Data Jpa
Testing Con Spring Test
Testing Controladores Spring Mvc Con Thymeleaf
Testing Con Spring Test
Testing Controladores Rest Con Json
Testing Con Spring Test
Testing De Aplicaciones Reactivas Webflux
Testing Con Spring Test
Testing De Seguridad Spring Security
Testing Con Spring Test
Testing Con Apache Kafka
Testing Con Spring Test
Integración Con Angular
Integración Frontend
Integración Con React
Integración Frontend
Integración Con Vue
Integración Frontend
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender la arquitectura y las responsabilidades separadas de React (front-end) y Spring Boot (back-end).
- Aprender a configurar y conectar una aplicación React con un servicio API construido en Spring Boot.
- Dominar la comunicación entre el cliente y el servidor, abordando la recuperación, envío y actualización de datos.
- Implementar autenticación y autorización, asegurando una interacción segura entre usuario y aplicación.
- 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.