Contenido del curso

Características Adicionales y Herramientas

Postgres directo en React Server Components

Resumen

Conectar Postgres directamente desde un React Server Component en Next.js te permite ejecutar consultas SQL crudas sin pasar por una API intermedia, protegiendo tus secretos y enviando solo el resultado al navegador. Esta práctica es clave si buscas eficiencia, seguridad y menos código en el cliente.

¿Por qué usar Postgres directo en un React Server Component?

Los React Server Components ejecutan código en el servidor y nunca exponen su lógica al navegador. Esto cambia la forma en que piensas la conexión con la base de datos.

En lugar de montar un endpoint REST o GraphQL, puedes importar tu cliente de Postgres dentro del componente y consultar la tabla directamente. Next.js separa el código entre cliente y servidor, así que tus credenciales y queries quedan blindadas.

¿Qué es un React Server Component? Es un componente que se ejecuta solo en el servidor, puede ser asíncrono y no envía su código JavaScript al navegador. Lo reconoces porque usa async y no tiene la directiva "use client".

La ventaja directa es doble: menos bundle en el cliente y menos superficie de ataque. Sin APIs públicas que escanear, los intentos automatizados de explotación se complican.

¿Cómo configurar la base de datos Expense Tracker en Postgres?

Antes de tocar el componente, necesitas la base lista. Abre tu terminal y entra a psql, el intérprete de comandos de Postgres [01:30].

Los pasos son simples y los puedes replicar tal cual:

  1. Crea la base de datos con CREATE DATABASE expense_tracker.
  2. Conéctate a ella desde psql o reabre con la base ya seleccionada.
  3. Crea la tabla expenses con los campos id, name (texto), amount (cantidad) y date con valor por defecto a la fecha actual.

El campo date con default a la fecha actual es importante: si no envías ese valor desde el formulario, Postgres lo rellena solo. Puedes verificar la estructura desde la línea de comandos o desde la interfaz gráfica de Postgres recargando la vista.

¿Cómo leer datos con SQL crudo desde el componente?

Dentro de app/expense-tracker vive una mini aplicación con su propia conexión a Postgres. La página principal es asíncrona, lo que confirma que es un React Server Component [03:45].

La función getExpenses vive en un archivo de acciones dentro de la misma carpeta de la página, una convención común en Next.js. Allí importas el cliente sql desde tu archivo de conexión, sin ORM ni capas intermedias.

La consulta es directa:

js const result = await sqlSELECT * FROM expenses ORDER BY date DESC;

Ese resultado se renderiza como tabla en el componente de servidor. Si la base está vacía, no verás errores de renderizado, solo una tabla limpia esperando datos.

¿Cómo insertar datos con form actions y FormData?

Aquí entra una de las piezas más potentes del modelo: las Server Actions. El formulario tiene dos input, uno con nombre name y otro con nombre amount, y su atributo action apunta directamente a la función addExpense importada desde el servidor.

No hay fetch, no hay endpoint, no hay URL escrita por ti. El cliente envía los datos como FormData, que es la forma nativa del navegador de mandar información al servidor.

¿Qué es FormData en Server Actions? Es el objeto estándar del navegador que empaqueta los campos de un formulario. En las acciones de Next.js lo recibes como parámetro y extraes los valores con formData.get("name").

Dentro de addExpense recuperas los nombres y haces el INSERT:

js await sqlINSERT INTO expenses (name, amount) VALUES (${name}, ${amount});

La interpolación con template literals del cliente de Postgres escapa los valores automáticamente, así evitas inyección SQL sin esfuerzo extra. La fecha no la pasas porque el default de Postgres se encarga.

¿Por qué la UI no se actualiza después de insertar?

Al agregar un registro, el cliente no refleja los datos nuevos. Tienes dos caminos para resolverlo.

  • Forzar un window.location.reload() desde el navegador, la opción más rústica.
  • Usar revalidatePath de Next.js, que es la opción recomendada.

revalidatePath("/expense-tracker") le indica a Next.js que invalide la caché de esa ruta y vuelva a generar la página con los datos frescos. El refresh es mucho más rápido que un reload completo del navegador [09:20].

¿Por qué este patrón es más seguro que una API tradicional?

Cuando inspeccionas la pestaña de red al enviar el formulario, no ves un endpoint claro tipo /api/expenses. Next.js genera identificadores internos que rotan y mapean cada acción del servidor a la función correcta sin exponer rutas estables.

Esto cambia las reglas del juego en seguridad. Los ataques automatizados suelen escanear APIs abiertas para encontrar mutaciones vulnerables. Con Server Actions esa superficie desaparece o se vuelve impredecible.

Sumado a eso, los secretos de tu backend, como cadenas de conexión a Postgres, viven solo en el servidor. El navegador recibe HTML ya renderizado, nunca el código que lo generó. Tu aplicación termina siendo más eficiente y mucho más difícil de atacar.

¿Ya probaste mover una de tus consultas a un Server Component? Cuéntame en los comentarios qué tan distinto se siente quitar la capa de API.