Integración de React Server Components con PostgreSQL

Clase 5 de 24Curso de Next.js Avanzado

Resumen

La integración de React Server Components con bases de datos como PostgreSQL ofrece una arquitectura potente y segura para manejar datos sensibles en aplicaciones modernas. Aquí exploramos cómo construir una aplicación con esta tecnología, realizando consultas SQL sin intermediarios y maximizando la seguridad y eficiencia de tu backend.

¿Qué ventajas ofrecen los React Server Components para proteger datos?

  • Protección del código del navegador: React Server Components permiten que el código sensible permanezca en el servidor, enviando al cliente solo el HTML necesario.
  • Minimización de exposición: Los navegadores no acceden directamente a las APIs o secretos del servidor, reduciendo riesgos de seguridad.
  • Separación de lógica cliente-servidor: Next.js gestiona esta separación automáticamente, facilitando la implementación de buenas prácticas.

¿Cómo conectar PostgreSQL directamente desde un React Server Component?

  1. Configuración de la base de datos:

    • Utiliza psql para crear la base de datos y tablas. En este ejemplo:

      CREATE DATABASE "expense_tracker"; \c expense_tracker CREATE TABLE expenses ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, amount NUMERIC NOT NULL, date TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
    • Verifica la estructura desde la línea de comandos o una GUI de PostgreSQL.

  2. Conexión en Next.js:

    • Configura la conexión en un archivo dedicado. Usa librerías como pg:

      const { Pool } = require('pg'); const pool = new Pool({ connectionString: process.env.DATABASE_URL, }); module.exports = pool;
  3. Consultas directas a SQL:

    • Define funciones para leer y mutar datos:

      const getExpenses = async () => { const result = await pool.query('SELECT * FROM expenses ORDER BY date DESC'); return result.rows; }; const addExpense = async (name, amount) => { await pool.query('INSERT INTO expenses (name, amount) VALUES ($1, $2)', [name, amount]); };

¿Cómo integrar consultas con un React Server Component?

  • Uso de funciones asincrónicas: Los componentes de servidor pueden llamar funciones SQL directamente sin intermediarios como ORMs.

  • Ejemplo de lectura y renderizado:

    import { getExpenses } from './db'; export default async function ExpenseTracker() { const expenses = await getExpenses(); return ( <table> <thead> <tr><th>Name</th><th>Amount</th><th>Date</th></tr> </thead> <tbody> {expenses.map(expense => ( <tr key={expense.id}> <td>{expense.name}</td> <td>{expense.amount}</td> <td>{expense.date}</td> </tr> ))} </tbody> </table> ); }

¿Cómo manejar mutaciones desde el cliente?

  • Uso de formularios y acciones:

    'use client'; const handleSubmit = async (formData) => { const name = formData.get('name'); const amount = formData.get('amount'); await fetch('/add-expense', { method: 'POST', body: JSON.stringify({ name, amount }) }); };
  • Revalidación de datos en Next.js:

    • Para actualizar automáticamente la UI tras una mutación:

      import { revalidatePath } from 'next/cache'; await revalidatePath('/expense-tracker');

¿Por qué es más seguro trabajar de esta forma?

  • API oculta al cliente: Next.js genera rutas dinámicas protegidas, dificultando el acceso malicioso.
  • Datos sensibles solo en el servidor: La lógica permanece oculta al navegador.
  • Protección contra ataques automatizados: Al evitar exponer rutas predecibles, se reducen las superficies de ataque.
      Integración de React Server Components con PostgreSQL