Concepto clave
En el desarrollo full-stack moderno, Server Actions representan un cambio de paradigma que permite ejecutar código del lado del servidor directamente desde componentes del cliente, sin necesidad de crear APIs REST tradicionales. Imagina que estás en un restaurante: en lugar de tener que llamar al mesero (API endpoint) para cada pedido, ahora puedes cocinar directamente en la cocina (servidor) desde tu mesa (cliente).
En SvelteKit, las Server Actions se definen en archivos +page.server.js o +server.js y se consumen desde componentes Svelte mediante la función enhance. Esto elimina la sobrecarga de crear controladores HTTP separados y simplifica significativamente el flujo de datos entre cliente y servidor. Para operaciones CRUD (Create, Read, Update, Delete), esto significa que puedes manejar toda la lógica de base de datos directamente donde tiene sentido: en el servidor, pero con una sintaxis que se siente como si estuvieras trabajando localmente.
Cómo funciona en la práctica
Vamos a implementar un CRUD completo para nuestra app de tareas en tiempo real. Primero, configuraremos una base de datos PostgreSQL usando Prisma como ORM. Luego, crearemos las Server Actions correspondientes para cada operación CRUD. El flujo es el siguiente:
Definir el esquema de la base de datos enprisma/schema.prismaCrear migraciones y sincronizar con la base de datosImplementar Server Actions ensrc/routes/tasks/+page.server.jsConsumir estas acciones desde el componente+page.svelteAgregar validaciones y manejo de errores
La magia ocurre cuando SvelteKit automáticamente serializa los datos entre cliente y servidor, manteniendo la seguridad (las acciones solo se ejecutan en el servidor) mientras proporciona una experiencia de desarrollo fluida.
Codigo en accion
Primero, definamos nuestra Server Action para crear una tarea:
// src/routes/tasks/+page.server.js
import { prisma } from '$lib/server/prisma';
import { fail } from '@sveltejs/kit';
export const actions = {
createTask: async ({ request }) => {
const data = await request.formData();
const title = data.get('title');
const description = data.get('description');
// Validación básica
if (!title || title.length < 3) {
return fail(400, {
error: 'El título debe tener al menos 3 caracteres',
title, description
});
}
try {
const task = await prisma.task.create({
data: {
title,
description: description || '',
completed: false,
createdAt: new Date()
}
});
return { success: true, task };
} catch (error) {
return fail(500, {
error: 'Error al crear la tarea',
title, description
});
}
}
};Ahora, veamos cómo consumir esta acción desde el componente:
<!-- src/routes/tasks/+page.svelte -->
<script>
import { enhance } from '$app/forms';
import { page } from '$app/stores';
let title = '';
let description = '';
</script>
<form method="POST" action="?/createTask" use:enhance>
<input
type="text"
name="title"
bind:value={title}
placeholder="Título de la tarea"
required
/>
<textarea
name="description"
bind:value={description}
placeholder="Descripción (opcional)"
></textarea>
<button type="submit">Crear Tarea</button>
</form>
{#if $page.form?.error}
<p style="color: red;">{$page.form.error}</p>
{/if}
{#if $page.form?.success}
<p style="color: green;">Tarea creada exitosamente!</p>
{/if}Errores comunes
Olvidar la validación del lado del servidor: Aunque valides en el cliente, siempre valida en el servidor. Los datos del cliente pueden ser manipulados.No manejar estados de carga: Cuando usasenhance, SvelteKit proporciona el estado$page.formque incluyesubmitting. Úsalo para deshabilitar botones durante el envío.Exponer errores internos al cliente: En producción, nunca devuelvas mensajes de error detallados de la base de datos. Usa logs en el servidor y mensajes genéricos al cliente.No limpiar formularios después del éxito: Después de una acción exitosa, limpia los campos del formulario para una mejor UX.Ignorar la concurrencia: En apps en tiempo real, múltiples usuarios pueden modificar los mismos datos. Implementa optimisic updates o versionado.
Checklist de dominio
Puedo crear una Server Action que interactúe con una base de datos realSé cómo validar datos tanto en cliente como en servidorImplementé al menos 3 operaciones CRUD completas usando Server ActionsManejo estados de error y éxito apropiadamente en la UIUso correctamente el estado$page.formpara feedback al usuarioConfiguré Prisma correctamente con mi base de datos PostgreSQLEntiendo la diferencia entre Server Actions y endpoints API tradicionales
Implementa CRUD completo para tareas con Server Actions
En este ejercicio, implementarás un sistema CRUD completo para la app de tareas usando Server Actions de SvelteKit.
- Configuración inicial: Asegúrate de tener PostgreSQL corriendo y configurado en tu
.env con la variable DATABASE_URL. Ejecuta npx prisma migrate dev para crear las tablas. - Crear (Create): Implementa la acción
createTask como se muestra en la lección, pero agrega validación para que la descripción no exceda 500 caracteres. - Leer (Read): Crea una Server Action
loadTasks que cargue todas las tareas desde la base de datos y muéstralas en una lista. - Actualizar (Update): Implementa
updateTask que permita marcar tareas como completadas/incompletas. Agrega un checkbox junto a cada tarea. - Eliminar (Delete): Crea
deleteTask con confirmación antes de eliminar. Usa un botón de eliminar por cada tarea. - Mejoras: Agrega paginación (10 tareas por página) y ordenamiento por fecha de creación descendente.
Entrega: Un repositorio Git con todo el código funcionando y un README que explique tu implementación.
Pistas- Usa el hook `use:enhance` en todos tus formularios para mejor UX
- Para la paginación, considera usar `skip` y `take` en las queries de Prisma
- Implementa optimistic updates para que la UI responda inmediatamente antes de la confirmación del servidor
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.