Acciones
Agregado en:
astro@4.15
Las Acciones de Astro te permiten definir y llamar funciones de backend con seguridad de tipos. Las acciones realizan la obtención de datos, el análisis de JSON y la validación de entradas por ti. Esto puede reducir considerablemente la cantidad de código repetitivo necesario en comparación con el uso de un endpoint API.
Usa acciones en lugar de endpoints API para una comunicación fluida entre el código del cliente y el servidor, y para:
- Validar automáticamente las entradas de datos JSON y de formularios usando validación Zod.
- Generar funciones con seguridad de tipos para llamar a tu backend desde el cliente e incluso desde acciones de formularios HTML. No es necesario hacer llamadas manuales con
fetch()
. - Estandarizar los errores del backend con el objeto
ActionError
.
Uso básico
Sección titulada «Uso básico»Las acciones se definen en un objeto server
exportado desde src/actions/index.ts
:
import { defineAction } from 'astro:actions';import { z } from 'astro:schema';
export const server = { myAction: defineAction({ /* ... */ })}
Tus acciones están disponibles como funciones desde el módulo astro:actions
. Importa actions
y llámalas del lado del cliente dentro de un componente de un framework de UI, una solicitud POST de un formulario, o usando una etiqueta <script>
en un componente Astro.
Cuando llamas a una acción, esta devuelve un objeto que contiene ya sea data
con el resultado serializado en JSON, o error
con los errores que se hayan producido.
------
<script>import { actions } from 'astro:actions';
async () => { const { data, error } = await actions.myAction({ /* ... */ });}</script>
Escribe tu primera acción
Sección titulada «Escribe tu primera acción»Sigue estos pasos para definir una acción y llamarla desde una etiqueta script
en tu página Astro.
-
Crea un archivo
src/actions/index.ts
y exporta un objetoserver
.src/actions/index.ts export const server = {// declaraciones de acciones} -
Importa la utilidad
defineAction()
desdeastro:actions
y el objetoz
desdeastro:schema
.src/actions/index.ts import { defineAction } from 'astro:actions';import { z } from 'astro:schema';export const server = {// declaraciones de acciones} -
Usa la utilidad
defineAction()
para definir una acción llamadagetGreeting
. La propiedadinput
se usará para validar los parámetros de entrada con un esquema de Zod y la funciónhandler()
incluye la lógica del backend que se ejecutará en el servidor.src/actions/index.ts import { defineAction } from 'astro:actions';import { z } from 'astro:schema';export const server = {getGreeting: defineAction({input: z.object({name: z.string(),}),handler: async (input) => {return `Hola, ${input.name}!`}})} -
Crea un componente Astro con un botón que, al hacer clic, obtenga un saludo usando tu acción
getGreeting
.src/pages/index.astro ------<button>Get greeting</button><script>const button = document.querySelector('button');button?.addEventListener('click', async () => {// Mostrar una ventana emergente con el saludo de la acción});</script> -
Para usar tu acción, importa
actions
desdeastro:actions
y luego llama aactions.getGreeting()
en el manejador del clic. La opciónname
se enviará alhandler()
de tu acción en el servidor y, si no hay errores, el resultado estará disponible en la propiedaddata
.src/pages/index.astro ------<button>Get greeting</button><script>import { actions } from 'astro:actions';const button = document.querySelector('button');button?.addEventListener('click', async () => {// Mostrar una ventana emergente con el saludo de la acciónconst { data, error } = await actions.getGreeting({ name: "Houston" });if (!error) alert(data);})</script>
defineAction()
y sus propiedades.
Organización de las acciones
Sección titulada «Organización de las acciones»Todas las acciones en tu proyecto deben ser exportadas desde el objeto server
en el archivo src/actions/index.ts
. Puedes definir las acciones directamente ahí o mover las definiciones a archivos separados e importarlas. Incluso puedes agrupar funciones relacionadas en objetos anidados.
Por ejemplo, para agrupar todas tus acciones de usuario, puedes crear un archivo src/actions/user.ts
y anidar las definiciones de getUser
y createUser
dentro de un solo objeto user
.
import { defineAction } from 'astro:actions';
export const user = { getUser: defineAction(/* ... */), createUser: defineAction(/* ... */),}
Luego, puedes importar este objeto user
en tu archivo src/actions/index.ts
y agregarlo como una clave de primer nivel al objeto server
, junto con las demás acciones:
import { user } from './user';
export const server = { myAction: defineAction({ /* ... */ }), user,}
Ahora, todas tus acciones de usuario se pueden llamar desde el objeto actions.user
:
actions.user.getUser()
actions.user.createUser()
Manejo de los datos retornados
Sección titulada «Manejo de los datos retornados»Las acciones devuelven un objeto que contiene ya sea data
con el valor retornado con seguridad de tipos de tu handler()
, o un error
con cualquier error del backend. Los errores pueden venir de fallos de validación en la propiedad input
o de errores lanzados dentro del handler()
.
Las acciones devuelven un formato de datos personalizado que puede manejar Date
, Map
, Set
y URL
usando la biblioteca Devalue. Por lo tanto, no puedes inspeccionar fácilmente la respuesta desde la red como con el JSON común. Para depurar, puedes inspeccionar el objeto data
que devuelven las acciones.
handler()
para más detalles.
Comprobando errores
Sección titulada «Comprobando errores»Es mejor verificar si hay un error
antes de usar la propiedad data
. Esto te permite manejar los errores de antemano y asegura que data
esté definido sin necesidad de hacer una comprobación de undefined
.
const { data, error } = await actions.example();
if (error) { // manejar casos de error return;}// usar `data`
Accediendo a data
directamente sin comprobar errores
Sección titulada «Accediendo a data directamente sin comprobar errores»Para omitir el manejo de errores, por ejemplo mientras haces prototipos o usas una librería que capture los errores por ti, usa la propiedad .orThrow()
en la llamada a tu acción para lanzar errores en lugar de devolver un error
. Esto devolverá directamente el data
de la acción.
Este ejemplo llama a una acción likePost()
que devuelve el número actualizado de “likes” como un number
desde el handler
de la acción:
const updatedLikes = await actions.likePost.orThrow({ postId: 'example' });// ^ tipo: number
Manejo de errores del backend en tu acción
Sección titulada «Manejo de errores del backend en tu acción»Puedes usar la clase ActionError
para lanzar un error desde el handler()
de tu acción, como “no encontrado” cuando falta una entrada en la base de datos, o “no autorizado” cuando un usuario no ha iniciado sesión. Esto tiene dos beneficios principales sobre devolver undefined
:
-
Puedes establecer un código de estado como
404 - Not Found
o401 - Unauthorized
. Esto mejora la depuración de errores tanto en desarrollo como en producción, permitiéndote ver el código de estado de cada solicitud. -
En el código de tu aplicación, todos los errores se pasan al objeto
error
en el resultado de la acción. Esto evita la necesidad de hacer comprobaciones deundefined
en los datos y permite mostrar mensajes específicos al usuario según el error ocurrido.
Creando un ActionError
Sección titulada «Creando un ActionError»Para lanzar un error, importa la clase ActionError()
desde el módulo astro:actions
. Pásale un código de estado legible para humanos (por ejemplo, "NOT_FOUND"
o "BAD_REQUEST"
), y un mensaje opcional para brindar más información sobre el error.
Este ejemplo lanza un error desde una acción likePost
cuando el usuario no ha iniciado sesión, después de verificar una cookie hipotética llamada “user-session” para autenticación:
import { defineAction, ActionError } from "astro:actions";import { z } from "astro:schema";
export const server = { likePost: defineAction({ input: z.object({ postId: z.string() }), handler: async (input, ctx) => { if (!ctx.cookies.has('user-session')) { throw new ActionError({ code: "UNAUTHORIZED", message: "El usuario debe haber iniciado sesión.", }); }
// De lo contrario, darle "like" a la publicación }, }),};
Manejo de un ActionError
Sección titulada «Manejo de un ActionError»Para manejar este error, puedes llamar a la acción desde tu aplicación y verificar si está presente una propiedad error
. Esta propiedad será de tipo ActionError
y contendrá tu code
y message
.
En el siguiente ejemplo, un componente LikeButton.tsx
llama a la acción likePost()
al hacer clic. Si ocurre un error de autenticación, se utiliza el atributo error.code
para determinar si se debe mostrar un enlace de inicio de sesión:
import { actions } from 'astro:actions';import { useState } from 'preact/hooks';
export function LikeButton({ postId }: { postId: string }) { const [showLogin, setShowLogin] = useState(false); return ( <> { showLogin && <a href="/signin">Inicia sesión para darle like a una publicación.</a> } <button onClick={async () => { const { data, error } = await actions.likePost({ postId }); if (error?.code === 'UNAUTHORIZED') setShowLogin(true); // Retorno temprano para errores inesperados else if (error) return; // Actualizar me gusta }}> Me gusta </button> </> )}
Manejo de redirecciones desde el cliente
Sección titulada «Manejo de redirecciones desde el cliente»Al llamar a acciones desde el cliente, puedes integrarlas con una librería del lado del cliente como react-router
, o usar la función navigate()
de Astro para redirigir a una nueva página cuando una acción se complete con éxito.
Este ejemplo navega a la página principal después de que una acción logout
se ejecute correctamente:
import { actions } from 'astro:actions';import { navigate } from 'astro:transitions/client';
export function LogoutButton() { return ( <button onClick={async () => { const { error } = await actions.logout(); if (!error) navigate('/'); }}> Cerrar sesión </button> );}
Aceptar datos de formulario en una acción
Sección titulada «Aceptar datos de formulario en una acción»Las acciones aceptan datos JSON por defecto. Para aceptar datos de formulario desde un formulario HTML, establece accept: 'form'
en la llamada a defineAction()
:
import { defineAction } from 'astro:actions';import { z } from 'astro:schema';
export const server = { comment: defineAction({ accept: 'form', input: z.object(/* ... */), handler: async (input) => { /* ... */ }, })}
Validación de datos de formulario
Sección titulada «Validación de datos de formulario»Las acciones convertirán los datos del formulario enviado en un objeto, usando el valor del atributo name
de cada input como claves del objeto. Por ejemplo, un formulario que contenga <input name="search">
se convertirá en un objeto como { search: 'valor ingresado por el usuario' }
. El esquema input
de tu acción se usará para validar este objeto.
Para recibir el objeto FormData
sin procesar directamente en el handler de tu acción, en lugar de un objeto ya parseado, omite la propiedad input
en la definición de tu acción.
El siguiente ejemplo muestra un formulario validado para la suscripción a un newsletter que acepta el email del usuario y requiere que acepte los términos y condiciones mediante una casilla de verificación.
-
Crea un componente de formulario HTML con atributos
name
únicos en cada campo de entrada:src/components/Newsletter.astro <form><label for="email">Correo Electrónico</label><input id="email" required type="email" name="email" /><label><input required type="checkbox" name="terms">Acepto los términos de servicio</label><button>Registrarse</button></form> -
Define una acción
newsletter
para manejar el formulario enviado. Valida el campoemail
usando el validadorz.string().email()
, y la casillaterms
conz.boolean()
:src/actions/index.ts import { defineAction } from 'astro:actions';import { z } from 'astro:schema';export const server = {newsletter: defineAction({accept: 'form',input: z.object({email: z.string().email(),terms: z.boolean(),}),handler: async ({ email, terms }) => { /* ... */ },})}Consulta la referencia de la API deinput
para ver todos los validadores de formulario disponibles. -
Agrega un
<script>
al formulario HTML para enviar los datos del usuario. Este ejemplo sobrescribe el comportamiento predeterminado del formulario para llamar aactions.newsletter()
y redirige a/confirmation
usando la funciónnavigate()
:src/components/Newsletter.astro <form>7 collapsed lines<label for="email">Correo Electrónico</label><input id="email" required type="email" name="email" /><label><input required type="checkbox" name="terms">Acepto los términos de servicio</label><button>Registrarse</button></form><script>import { actions } from 'astro:actions';import { navigate } from 'astro:transitions/client';const form = document.querySelector('form');form?.addEventListener('submit', async (event) => {event.preventDefault();const formData = new FormData(form);const { error } = await actions.newsletter(formData);if (!error) navigate('/confirmation');})</script>Consulta “Llamar acciones desde una acción de formulario HTML” para una forma alternativa de enviar datos de formulario.
Mostrar errores de validación en el formulario
Sección titulada «Mostrar errores de validación en el formulario»Puedes validar los campos del formulario antes de enviarlo usando atributos nativos de validación HTML como required
, type="email"
y pattern
. Para validaciones más complejas en el backend, puedes usar la función utilitaria isInputError()
.
Para obtener los errores de entrada, utiliza isInputError()
para verificar si un error fue causado por datos inválidos. Los errores de entrada contienen un objeto fields
con mensajes para cada campo que falló la validación. Puedes usar estos mensajes para indicarle al usuario que corrija su envío.
El siguiente ejemplo verifica el error con isInputError()
, luego comprueba si el error está en el campo de email y finalmente crea un mensaje con los errores. Puedes usar manipulación del DOM en JavaScript o tu framework de UI preferido para mostrar este mensaje a los usuarios.
import { actions, isInputError } from 'astro:actions';
const form = document.querySelector('form');const formData = new FormData(form);const { error } = await actions.newsletter(formData);if (isInputError(error)) { // Manejar errores de entrada. if (error.fields.email) { const message = error.fields.email.join(', '); }}
Llamar acciones desde una acción de formulario HTML
Sección titulada «Llamar acciones desde una acción de formulario HTML»Las páginas deben renderizarse bajo demanda al llamar acciones usando una acción de formulario. Asegúrate de desactivar el prerenderizado en la página antes de usar esta API.
Puedes habilitar envíos de formularios sin JavaScript usando atributos estándar en cualquier elemento <form>
. Los envíos de formularios sin JavaScript del lado cliente pueden ser útiles como respaldo cuando JavaScript no carga o si prefieres manejar formularios completamente desde el servidor.
Llamar a Astro.getActionResult() en el servidor devuelve el resultado de tu envío de formulario (data
o error
), y puede usarse para redirigir dinámicamente, manejar errores de formulario, actualizar la interfaz y más.
Para llamar una acción desde un formulario HTML, agrega method="POST"
a tu <form>
, luego asigna el atributo action
usando tu acción, por ejemplo action={actions.logout}
. Esto configurará el atributo action
con una cadena de consulta que es manejada automáticamente por el servidor.
Por ejemplo, este componente Astro llama a la acción logout
cuando se hace clic en el botón y recarga la página actual:
---import { actions } from 'astro:actions';---
<form method="POST" action={actions.logout}> <button>Cerrar sesión</button></form>
Es posible que se necesiten atributos adicionales en el elemento <form>
para una validación correcta del esquema con Zod. Por ejemplo, para incluir cargas de archivos, agrega enctype="multipart/form-data"
para asegurar que los archivos se envíen en un formato reconocido correctamente por z.instanceof(File)
:
---import { actions } from 'astro:actions';---<form method="POST" action={actions.upload} enctype="multipart/form-data" > <label for="file">Subir archivo</label> <input type="file" id="file" name="file" /> <button type="submit">Enviar</button></form>
Redirigir al completar la acción
Sección titulada «Redirigir al completar la acción»Si necesitas redirigir a una nueva ruta cuando la acción sea exitosa, puedes usar el resultado de la acción en el servidor. Un ejemplo común es crear un registro de producto y redirigir a la página del nuevo producto, por ejemplo, /products/[id]
.
Por ejemplo, imagina que tienes una acción createProduct
que devuelve el id del producto generado:
import { defineAction } from 'astro:actions';import { z } from 'astro:schema';
export const server = { createProduct: defineAction({ accept: 'form', input: z.object({ /* ... */ }), handler: async (input) => { const product = await persistToDatabase(input); return { id: product.id }; }, })}
Puedes obtener el resultado de la acción desde tu componente Astro llamando a Astro.getActionResult()
. Esto devuelve un objeto que contiene las propiedades data
o error
cuando se llama a una acción, o undefined
si la acción no fue llamada durante esta petición.
Usa la propiedad data
para construir una URL que usarás con Astro.redirect()
:
---import { actions } from 'astro:actions';
const result = Astro.getActionResult(actions.createProduct);if (result && !result.error) { return Astro.redirect(`/products/${result.data.id}`);}---
<form method="POST" action={actions.createProduct}> <!--...--></form>
Manejar errores de acciones en formularios
Sección titulada «Manejar errores de acciones en formularios»Llamar a Astro.getActionResult()
en el componente Astro que contiene tu formulario te da acceso a los objetos data
y error
para manejar errores personalizados.
El siguiente ejemplo muestra un mensaje general de fallo cuando la acción newsletter
falla:
---import { actions } from 'astro:actions';
const result = Astro.getActionResult(actions.newsletter);---
{result?.error && ( <p class="error">No se pudo inscribir. Por favor, inténtalo de nuevo más tarde.</p>)}<form method="POST" action={actions.newsletter}> <label> Correo electrónico <input required type="email" name="email" /> </label> <button>Inscribirse</button></form>
Para mayor personalización, puedes usar la utilidad isInputError()
para verificar si un error fue causado por una entrada inválida.
El siguiente ejemplo muestra un mensaje de error debajo del campo de entrada email
cuando se envía un correo electrónico inválido:
---import { actions, isInputError } from 'astro:actions';
const result = Astro.getActionResult(actions.newsletter);const inputErrors = isInputError(result?.error) ? result.error.fields : {};---
<form method="POST" action={actions.newsletter}> <label> Correo electrónico <input required type="email" name="email" aria-describedby="error" /> </label> {inputErrors.email && <p id="error">{inputErrors.email.join(',')}</p>} <button>Registrarse</button></form>
Conservar valores de entrada en caso de error
Sección titulada «Conservar valores de entrada en caso de error»Los campos de entrada se limpiarán cada vez que se envíe un formulario. Para mantener los valores de entrada, puedes activar las transiciones de vista y aplicar la directiva transition:persist
a cada campo de entrada:
<input transition:persist required type="email" name="email" />
Actualizar la interfaz con el resultado de una acción de formulario
Sección titulada «Actualizar la interfaz con el resultado de una acción de formulario»Para usar el valor retornado por una acción y mostrar una notificación al usuario en caso de éxito, pasa la acción a Astro.getActionResult()
. Usa la propiedad data
retornada para renderizar la interfaz que deseas mostrar.
Este ejemplo utiliza la propiedad productName
retornada por una acción addToCart
para mostrar un mensaje de éxito.
---import { actions } from 'astro:actions';
const result = Astro.getActionResult(actions.addToCart);---
{result && !result.error && ( <p class="success">Agregado {result.data.productName} al carrito</p>)}
<!--...-->
Avanzado: Persistir los resultados de una acción con una sesión
Sección titulada «Avanzado: Persistir los resultados de una acción con una sesión»
Agregado en:
astro@5.0.0
Los resultados de las acciones se muestran como una solicitud POST. Esto significa que el resultado se restablecerá a undefined
cuando un usuario cierre y vuelva a visitar la página. Además, el usuario verá un cuadro de diálogo de “confirmar reenvío del formulario” si intenta refrescar la página.
Para personalizar este comportamiento, puedes agregar un middleware para manejar manualmente el resultado de la acción. Puedes optar por persistir el resultado de la acción usando cookies o almacenamiento de sesión.
Comienza creando un archivo de middleware e importando la utilidad getActionContext()
desde astro:actions
. Esta función devuelve un objeto action
con información sobre la solicitud de acción entrante, incluyendo el manejador de la acción y si la acción fue llamada desde un formulario HTML. getActionContext()
también retorna las funciones setActionResult()
y serializeActionResult()
para establecer programáticamente el valor que devolverá Astro.getActionResult()
.
import { defineMiddleware } from 'astro:middleware';import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => { const { action, setActionResult, serializeActionResult } = getActionContext(context); if (action?.calledFrom === 'form') { const result = await action.handler(); // ... manejar el resultado de la acción setActionResult(action.name, serializeActionResult(result)); } return next();});
Una práctica común para persistir los resultados de formularios HTML es el patrón POST
/ Redirect / GET
. Este redireccionamiento elimina el diálogo de “confirmar reenvío del formulario” cuando se actualiza la página y permite que los resultados de las acciones se mantengan durante la sesión del usuario.
Este ejemplo aplica el patrón POST
/ Redirect / GET
a todas las envíos de formularios usando el almacenamiento de sesión con el adaptador de servidor de Netlify instalado. Los resultados de las acciones se escriben en un almacén de sesión usando Netlify Blob y se recuperan después de un redireccionamiento usando un ID de sesión:
import { defineMiddleware } from 'astro:middleware';import { getActionContext } from 'astro:actions';import { randomUUID } from "node:crypto";import { getStore } from "@netlify/blobs";
export const onRequest = defineMiddleware(async (context, next) => { // Saltar solicitudes para páginas prerenderizadas if (context.isPrerendered) return next();
const { action, setActionResult, serializeActionResult } = getActionContext(context); // Crea un almacén de Blobs para persistir los resultados de las acciones con Netlify Blob const actionStore = getStore("action-session");
// Si un resultado de acción fue enviado como una cookie, establece el resultado // para que sea accesible desde `Astro.getActionResult()` const sessionId = context.cookies.get("action-session-id")?.value; const session = sessionId ? await actionStore.get(sessionId, { type: "json", }) : undefined;
if (session) { setActionResult(session.actionName, session.actionResult);
// Opcional: eliminar la sesión después de que la página se haya renderizado. // Siéntete libre de implementar tu propia estrategia de persistencia await actionStore.delete(sessionId); context.cookies.delete("action-session-id"); return next(); }
// Si una acción fue llamada desde un formulario HTML, // llama al controlador de la acción y redirige a la página de destino if (action?.calledFrom === "form") { const actionResult = await action.handler();
// Persiste el resultado de la acción usando almacenamiento de sesión const sessionId = randomUUID(); await actionStore.setJSON(sessionId, { actionName: action.name, actionResult: serializeActionResult(actionResult), });
// Pasar el ID de sesión como una cookie // para ser recuperado después de redirigir a la página context.cookies.set("action-session-id", sessionId);
// Redirigir de vuelta a la página anterior en caso de error if (actionResult.error) { const referer = context.request.headers.get("Referer"); if (!referer) { throw new Error( "Internal: Referer unexpectedly missing from Action POST request.", ); } return context.redirect(referer); }
// Redirigir a la página de destino en caso de éxito return context.redirect(context.originPathname); }
return next();});
Seguridad al usar acciones
Sección titulada «Seguridad al usar acciones»Las acciones son accesibles como endpoints públicos basados en el nombre de la acción. Por ejemplo, la acción blog.like()
será accesible desde /_actions/blog.like
. Esto es útil para realizar pruebas unitarias de los resultados de la acción y para depurar errores en producción. Sin embargo, esto significa que debes implementar las mismas verificaciones de autorización que considerarías para los endpoints de API y las páginas renderizadas bajo demanda.
Autorizar usuarios desde un handler de acción
Sección titulada «Autorizar usuarios desde un handler de acción»Para autorizar las solicitudes de acción, agrega una verificación de autenticación en el handler de tu acción. Puedes usar una biblioteca de autenticación para manejar la gestión de sesiones y la información del usuario.
Las acciones exponen el objeto completo APIContext
para acceder a propiedades pasadas desde middleware usando context.locals
. Cuando un usuario no está autorizado, puedes lanzar un ActionError
con el código UNAUTHORIZED
:
import { defineAction, ActionError } from 'astro:actions';
export const server = { getUserSettings: defineAction({ handler: async (_input, context) => { if (!context.locals.user) { throw new ActionError({ code: 'UNAUTHORIZED' }); }
return { /* datos en caso de éxito */ }; } })}
Restringir acciones desde un middleware
Sección titulada «Restringir acciones desde un middleware»
Agregado en:
astro@5.0.0
Astro recomienda autorizar las sesiones de usuario desde el manejador de acciones para respetar los niveles de permiso y la limitación de tasa por acción. Sin embargo, también puedes restringir las solicitudes a todas las acciones (o un subconjunto de ellas) desde el middleware.
Usa la función getActionContext()
en tu middleware para obtener información sobre cualquier solicitud de acción entrante. Esto incluye el nombre de la acción y si esa acción fue llamada usando una función RPC del lado del cliente (por ejemplo, actions.blog.like()
) o un formulario HTML.
El siguiente ejemplo rechaza todas las solicitudes de acción que no tengan un token de sesión válido. Si la verificación falla, se devuelve una respuesta de “Forbidden”. Nota: este método asegura que las acciones solo sean accesibles cuando hay una sesión presente, pero no es un sustituto para una autorización segura.
import { defineMiddleware } from 'astro:middleware';import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => { const { action } = getActionContext(context); // Verificar si la acción fue llamada desde una función del lado del cliente if (action?.calledFrom === 'rpc') { // Si es así, verifica que exista un token de sesión de usuario if (!context.cookies.has('user-session')) { return new Response('Forbidden', { status: 403 }); } }
context.cookies.set('user-session', /* token de sesión */); return next();});
Llamar a acciones desde componentes Astro y endpoints del servidor
Sección titulada «Llamar a acciones desde componentes Astro y endpoints del servidor»Puedes llamar a acciones directamente desde los scripts de componentes Astro usando el envoltorio Astro.callAction()
(o context.callAction()
cuando usas un endpoint del servidor). Esto es común para reutilizar la lógica de tus acciones en otro código del servidor.
Pasa la acción como primer argumento y cualquier parámetro de entrada como segundo argumento. Esto devuelve los mismos objetos data
y error
que recibes al llamar a acciones desde el cliente:
---import { actions } from 'astro:actions';
const searchQuery = Astro.url.searchParams.get('search');if (searchQuery) { const { data, error } = await Astro.callAction(actions.findProduct, { query: searchQuery }); // maneja el resultado}---