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:
| ID | Nombre | Precio | Stock |
|---|---|---|---|
| 1 | Laptop | 1200 | 10 |
| 2 | Mouse | 25 | 50 |
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
- 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.
- 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
formDataantes de procesarlo. - Ignorar revalidación de caché: Después de mutar datos (como crear o actualizar), olvidar llamar a
revalidatePathorevalidateTaghace que la UI muestre información obsoleta. Inclúyelo siempre en tus acciones para mantener la coherencia. - 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.
- 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
revalidatePathorevalidateTagpara 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:
- Configura un proyecto Next.js 15 con App Router y una base de datos SQLite usando Prisma.
- Define un modelo de Usuario en
prisma/schema.prismacon campos: id, nombre, email, y fecha de creación. - Crea un archivo
app/users/actions.jscon 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).
- Implementa una página en
app/users/page.jsque:- 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.
- Muestre una lista de usuarios en una tabla HTML, usando
- Prueba el flujo completo: agrega un usuario, edita su nombre, y elimínalo, verificando que la UI se actualice sin recargar.
- 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.