Práctica: Crear un CRUD con Server Actions

Video
30 min~5 min lectura

Reproductor de video

Concepto clave

Las Server Actions en Next.js 15 son funciones que se ejecutan exclusivamente en el servidor, permitiendo operaciones de datos seguras sin exponer APIs públicas. Piensa en ellas como cajeros automáticos: tu aplicación cliente (el usuario) inserta una solicitud (como retirar dinero), pero toda la lógica de validación y procesamiento ocurre dentro del servidor (el banco), manteniendo la seguridad de las credenciales y el saldo.

En un CRUD tradicional con APIs REST, necesitas crear endpoints separados para cada operación (GET, POST, PUT, DELETE), lo que puede volverse complejo. Con Server Actions, defines funciones directas en tus componentes de servidor que manejan creación, lectura, actualización y eliminación en un solo lugar, reduciendo la sobrecarga de configuración. Esto es especialmente útil en aplicaciones full-stack donde la velocidad y la seguridad son prioritarias.

Cómo funciona en la práctica

Imagina que estás construyendo una app de tareas. Primero, creas un componente de servidor en app/tasks/page.js. Dentro, defines Server Actions usando 'use server' al inicio de la función. Por ejemplo, para agregar una tarea:

'use server';
export async function addTask(formData) {
  const title = formData.get('title');
  // Validar y guardar en base de datos
  await db.tasks.create({ data: { title } });
  revalidatePath('/tasks');
}

Luego, en tu formulario cliente, llamas a esta acción con action={addTask}. Next.js maneja automáticamente la comunicación, enviando los datos del formulario al servidor, ejecutando la lógica y actualizando la UI con Streaming SSR para mostrar cambios en tiempo real sin recargar la página completa.

Caso de estudio

Vamos a aplicar esto a un sistema de inventario para una tienda online. Supongamos que tenemos una tabla de productos con estos datos:

IDNombrePrecioStock
1Laptop120010
2Mouse2550

Creamos Server Actions en app/inventory/actions.js para manejar operaciones CRUD:

  • createProduct: Toma datos de un formulario y los inserta en la base de datos.
  • getProducts: Recupera la lista de productos para mostrar en una tabla.
  • updateProduct: Actualiza el precio o stock basado en ID.
  • deleteProduct: Elimina un producto por ID, con validación de stock cero.

En la UI, usamos un formulario con action={createProduct} y una tabla que se actualiza dinámicamente gracias a revalidatePath. Esto permite al empleado de la tienda gestionar inventario en tiempo real, con feedback inmediato sobre errores como stock negativo.

Recuerda: Server Actions no reemplazan APIs públicas para integraciones externas, pero son ideales para operaciones internas donde controlas tanto el cliente como el servidor.

Errores comunes

  1. Olvidar 'use server': Si no incluyes esta directiva al inicio de tu función, Next.js intentará ejecutarla en el cliente, causando errores de seguridad o rendimiento. Siempre verifica que tus Server Actions estén marcadas correctamente.
  2. No validar datos de entrada: Confiar en datos del cliente sin sanitización puede llevar a inyecciones SQL o corrupción de datos. Usa bibliotecas como Zod para validar el formData antes de procesarlo.
  3. Ignorar revalidación de caché: Después de mutar datos (como crear o actualizar), olvidar llamar a revalidatePath o revalidateTag hace que la UI muestre información obsoleta. Inclúyelo siempre en tus acciones para mantener la coherencia.
  4. Usar Server Actions para cargas pesadas: Estas acciones son para operaciones rápidas; tareas como procesamiento de imágenes grandes deben delegarse a jobs en segundo plano para no bloquear respuestas.
  5. Exponer lógica sensible en errores Mostrar mensajes de error detallados puede filtrar información de la base de datos. Envía errores genéricos al cliente y registra los detalles en el servidor.

Checklist de dominio

  • Puedo crear una Server Action que maneje la creación de un recurso en una base de datos.
  • Sé cómo estructurar acciones para lectura, actualización y eliminación en un solo archivo.
  • Implemento validación de datos en el servidor antes de cualquier operación CRUD.
  • Uso revalidatePath o revalidateTag para actualizar la UI después de mutaciones.
  • Diferencio cuándo usar Server Actions (operaciones internas) vs APIs públicas (integraciones externas).
  • Manejo errores de forma segura, sin exponer detalles internos al cliente.
  • Optimizo el rendimiento evitando acciones bloqueantes en flujos críticos.

Construye un CRUD de Usuarios con Server Actions

En este ejercicio, crearás un sistema de gestión de usuarios para una app interna. Sigue estos pasos:

  1. Configura un proyecto Next.js 15 con App Router y una base de datos SQLite usando Prisma.
  2. Define un modelo de Usuario en prisma/schema.prisma con campos: id, nombre, email, y fecha de creación.
  3. Crea un archivo app/users/actions.js con Server Actions para:
    • createUser: Acepta nombre y email desde un formulario, valida que el email sea único, y guarda en la base de datos.
    • getUsers: Recupera todos los usuarios ordenados por fecha de creación.
    • updateUser: Permite actualizar el nombre de un usuario por ID.
    • deleteUser: Elimina un usuario por ID, solo si no tiene registros asociados (simula con una validación básica).
  4. Implementa una página en app/users/page.js que:
    • Muestre una lista de usuarios en una tabla HTML, usando getUsers.
    • Incluya un formulario para agregar nuevos usuarios, con action={createUser}.
    • Añada botones para editar y eliminar usuarios, que llamen a las acciones correspondientes.
  5. Prueba el flujo completo: agrega un usuario, edita su nombre, y elimínalo, verificando que la UI se actualice sin recargar.
Pistas
  • Usa 'use server' al inicio de cada función en actions.js para asegurar ejecución en el servidor.
  • Incluye revalidatePath('/users') en tus acciones de creación, actualización y eliminación para refrescar la lista automáticamente.
  • Para validar el email único, consulta la base de datos en createUser antes de insertar, y devuelve un error amigable si ya existe.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.