Referencia de la API de Actions
Añadido en:
astro@4.15.0
Las Actions te ayudan a construir un backend type-safe que puedes llamar desde código del cliente y formularios HTML. Todas las utilidades para definir y llamar actions se exponen a través del módulo astro:actions. Para ejemplos e instrucciones de uso, consulta la guía de Actions.
Importaciones desde astro:actions
Sección titulada “Importaciones desde astro:actions”import { ACTION_QUERY_PARAMS, ActionError, actions, defineAction, getActionContext, getActionPath, isActionError, isInputError, } from 'astro:actions';defineAction()
Sección titulada “defineAction()”Type: ({ accept, input, handler }) => ActionClient
Una utilidad para definir nuevas actions en el archivo src/actions/index.ts. Esta acepta una función handler() que contiene la lógica del servidor a ejecutar, y una propiedad opcional input para validar los parámetros de entrada en runtime.
import { defineAction } from 'astro:actions';import { z } from 'astro/zod';
export const server = { getGreeting: defineAction({ input: z.object({ name: z.string(), }), handler: async (input, context) => { return `Hello, ${input.name}!` } })}Propiedad handler()
Sección titulada “Propiedad handler()”Type: (input: TInputSchema, context: ActionAPIContext) => TOutput | Promise<TOutput>
Una función requerida que contiene la lógica del servidor a ejecutar cuando se llama la action. Los datos devueltos por el handler() se serializan automáticamente y se envían al llamador.
El handler() se llama con la entrada del usuario como primer argumento. Si se establece un validador de input, la entrada del usuario se validará antes de pasarse al handler. El segundo argumento es un subconjunto del objeto context de Astro.
Los valores de retorno se parsean usando la librería devalue. Esta soporta valores JSON e instancias de Date(), Map(), Set(), y URL().
Validador input
Sección titulada “Validador input”Type: ZodType | undefined
Una propiedad opcional que acepta un validador Zod (ej. Zod object, Zod discriminated union) para validar las entradas del handler en runtime. Si la action falla la validación, se devuelve un error BAD_REQUEST y no se llama al handler.
Si se omite input, el handler recibirá una entrada de tipo unknown para peticiones JSON y de tipo FormData para peticiones de formulario.
Propiedad accept
Sección titulada “Propiedad accept”Type: "form" | "json"
Default: json
Define el formato esperado por una action:
- Usa
formcuando tu action aceptaFormData. - Usa
json, el valor por defecto, para todos los demás casos.
Cuando tu action acepta entradas de formulario, el validador z.object() parseará automáticamente FormData a un objeto tipado. Todos los validadores Zod son soportados para validar tus entradas.
actions
Sección titulada “actions”Type: Record<string, ActionClient>
Un objeto que contiene todas tus actions con el nombre de la action como clave asociada a una función para llamar esta action.
------
<script>import { actions } from 'astro:actions';
async () => { const { data, error } = await actions.myAction({ /* ... */ });}</script>Para que Astro reconozca esta propiedad, puede que necesites reiniciar el dev server o ejecutar el comando astro sync (s + enter).
isInputError()
Sección titulada “isInputError()”Type: (error?: unknown) => boolean
Una utilidad usada para comprobar si un ActionError es un error de validación de entrada. Cuando el validador de input es un z.object(), los errores de entrada incluyen un objeto fields con mensajes de error agrupados por nombre.
isInputError().
isActionError()
Sección titulada “isActionError()”Type: (error?: unknown) => boolean
Una utilidad para comprobar si tu action lanzó un ActionError dentro de la propiedad handler. Esto es útil al estrechar el tipo de un error genérico.
------
<script>import { isActionError, actions } from 'astro:actions';
async () => { const { data, error } = await actions.myAction({ /* ... */ }); if (isActionError(error)) { // Handle action-specific errors console.log(error.code); }}</script>ActionError
Sección titulada “ActionError”El constructor ActionError() se usa para crear errores lanzados por un handler de una action. Este acepta una propiedad code que describe el error ocurrido (ejemplo: "UNAUTHORIZED"), y una propiedad opcional message con más detalles.
El siguiente ejemplo crea un nuevo ActionError cuando el usuario no está logueado:
import { defineAction, ActionError } from "astro:actions";
export const server = { getUserOrThrow: defineAction({ accept: 'form', handler: async (_, { locals }) => { if (locals.user?.name !== 'florian') { throw new ActionError({ code: 'UNAUTHORIZED', message: 'Not logged in', }); } return locals.user; }, }),}También puedes usar ActionError para estrechar el tipo de error al manejar los resultados de una action:
------
<script>import { ActionError, actions } from 'astro:actions';
async () => { const { data, error } = await actions.myAction({ /* ... */ }); if (error instanceof ActionError) { // Handle action-specific errors console.log(error.code); }}</script>Type: ActionErrorCode
Define una versión legible de un código de estado HTTP.
message
Sección titulada “message”Type: string
Una propiedad opcional para describir el error (ej. “El usuario debe estar logueado.”).
Type: string
Una propiedad opcional para pasar el stack trace.
getActionContext()
Sección titulada “getActionContext()”Type: (context: APIContext) => AstroActionContext
astro@5.0.0
Una función llamada desde tu handler de middleware para obtener información sobre peticiones de action entrantes. Esta devuelve un objeto action con información sobre la petición, un método deserializeActionResult(), y las funciones setActionResult() y serializeActionResult() para establecer programáticamente el valor devuelto por Astro.getActionResult().
getActionContext() te permite obtener y establecer programáticamente resultados de actions usando middleware, permitiéndote persistir resultados de actions desde formularios HTML, proteger peticiones de actions con comprobaciones de seguridad adicionales, y más.
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(); setActionResult(action.name, serializeActionResult(result)); } return next();});Type: { calledFrom: “rpc” | “form”; name: string; handler: () => Promise<SafeResult>; } | undefined
Un objeto que contiene información sobre una petición de action entrante. Está disponible desde getActionContext(), y proporciona el name de la action, el handler, y si la action fue llamada desde una función RPC del lado del cliente (ej. actions.newsletter()) o desde una action de formulario HTML.
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 === 'rpc' && action.name.startsWith('private')) { // Check for a valid session token } // ...});action.calledFrom
Sección titulada “action.calledFrom”Type: "rpc" | "form"
Si una action fue llamada usando una función RPC o una action de formulario HTML.
action.name
Sección titulada “action.name”Type: string
El nombre de la action. Útil para rastrear el origen del resultado de una action durante una redirección.
action.handler()
Sección titulada “action.handler()”Type: () => Promise<SafeResult>
Un método para llamar programáticamente una action y obtener el resultado.
setActionResult()
Sección titulada “setActionResult()”Type: (actionName: string, actionResult: SerializedActionResult) => void
Una función para establecer programáticamente el valor devuelto por Astro.getActionResult() en el middleware. Se le pasa el nombre de la action y un resultado de action serializado por serializeActionResult(). Llamar a esta función desde el middleware deshabilitará el manejo propio de resultados de actions de Astro.
Esto es útil cuando se llaman actions desde un formulario HTML para persistir y cargar resultados desde una sesión.
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(); // ... handle the action result setActionResult(action.name, serializeActionResult(result)); } return next();});serializeActionResult()
Sección titulada “serializeActionResult()”Type: (res: SafeResult) => SerializedActionResult
Serializa un resultado de action a JSON para su persistencia. Esto es necesario para manejar correctamente valores de retorno no JSON como Map o Date así como el objeto ActionError.
Llama a esta función al serializar un resultado de action para pasarlo a setActionResult():
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) { const result = await action.handler(); setActionResult(action.name, serializeActionResult(result)); } // ...});deserializeActionResult()
Sección titulada “deserializeActionResult()”Type: (res: SerializedActionResult) => SafeResult
Revierte el efecto de serializeActionResult() y devuelve un resultado de action a su estado original. Esto es útil para acceder a los objetos data y error en un resultado de action serializado.
getActionPath()
Sección titulada “getActionPath()”Type: (action: ActionClient) => string
astro@5.1.0
Una utilidad que acepta una action y devuelve una ruta URL para que puedas ejecutar una llamada a la action como una operación fetch() directamente. Esto te permite proporcionar detalles como headers personalizados cuando llamas a tu action. Luego, puedes manejar los datos devueltos con formato personalizado según sea necesario, igual que si hubieras llamado a una action directamente.
Este ejemplo muestra cómo llamar a una action like definida pasando el header Authorization y la opción keepalive:
<script>import { actions, getActionPath } from 'astro:actions'
await fetch(getActionPath(actions.like), { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer YOUR_TOKEN' }, body: JSON.stringify({ id: 'YOUR_ID' }), keepalive: true})</script>Este ejemplo muestra cómo llamar a la misma action like usando la API sendBeacon:
<script>import { actions, getActionPath } from 'astro:actions'
navigator.sendBeacon( getActionPath(actions.like), new Blob([JSON.stringify({ id: 'YOUR_ID' })], { type: 'application/json' }))</script>ACTION_QUERY_PARAMS
Sección titulada “ACTION_QUERY_PARAMS”Type: { actionName: string, actionPayload: string }
Un objeto que contiene los nombres de los parámetros de consulta usados internamente por Astro al manejar envíos de formularios con actions.
Cuando envías un formulario usando una action, los siguientes parámetros de consulta se añaden a la URL para rastrear la llamada a la action:
actionName- El parámetro de consulta que contiene el nombre de la action que se está llamandoactionPayload- El parámetro de consulta que contiene los datos del formulario serializados
Esta constante puede ser útil cuando necesitas limpiar URLs después de un envío de formulario. Por ejemplo, podrías querer eliminar los parámetros de consulta relacionados con la action durante una redirección:
import type { APIRoute } from "astro";import { ACTION_QUERY_PARAMS } from 'astro:actions'
export const GET: APIRoute = ({ params, request }) => { const link = request.url.searchParams; link.delete(ACTION_QUERY_PARAMS.actionName); link.delete(ACTION_QUERY_PARAMS.actionPayload);
return redirect(link, 303);};Tipos de astro:actions
Sección titulada “Tipos de astro:actions”import type { ActionAPIContext, ActionClient, ActionErrorCode, ActionInputSchema, ActionReturnType, SafeResult, } from 'astro:actions';ActionAPIContext
Sección titulada “ActionAPIContext”Un subconjunto del objeto context de Astro. Las siguientes propiedades no están disponibles: callAction, getActionResult, props, y redirect.
ActionClient
Sección titulada “ActionClient”Types:
(input?: any) => Promise<SafeResult>{ queryString?: string; orThrow: (input?: any) => Promise<Awaited<TOutput>>; }
Representa una action a ser llamada en el cliente. Puedes usarla como una función que acepta datos de entrada y devuelve una Promise con un objeto SafeResult que contiene el resultado de la action o errores de validación.
El siguiente ejemplo muestra cómo puedes proporcionar manejo de errores con una declaración if cuando falla el incremento del contador de likes:
------
<!-- your template -->
<script>import { actions } from 'astro:actions';
const post = document.querySelector('article');const button = document.querySelector('button');button?.addEventListener('click', async () => { const { data: updatedLikes, error } = await actions.likePost({ postId: post?.id }); if (error) { /* handle errors */ }})</script>Alternativamente, puedes usarla como un objeto que te da acceso al queryString y a un método alternativo orThrow().
ActionClient.queryString
Sección titulada “ActionClient.queryString”Type: string
Una representación en cadena de la action que puede usarse para construir URLs de actions de formulario. Esto puede ser útil cuando tu componente de formulario se usa en múltiples lugares pero necesitas redirigir a una URL diferente al enviar.
El siguiente ejemplo usa queryString para construir una URL que se pasará al atributo action del formulario a través de una prop personalizada:
---import { actions } from 'astro:actions';import FeedbackForm from "../components/FeedbackForm.astro";
const feedbackUrl = new URL('/feedback', Astro.url);feedbackUrl.search = actions.myAction.queryString;---<FeedbackForm sendTo={feedbackUrl.pathname} />ActionClient.orThrow()
Sección titulada “ActionClient.orThrow()”Type: (input?: any) => Promise<Awaited<TOutput>>
Un método que lanza un error en caso de fallo en lugar de devolver los errores. Esto es útil cuando quieres excepciones en lugar de manejo de errores.
El siguiente ejemplo usa orThrow() para omitir el manejo de errores cuando falla el incremento del contador de likes:
------
<!-- your template -->
<script>import { actions } from 'astro:actions';
const post = document.querySelector('article');const button = document.querySelector('button');button?.addEventListener('click', async () => { const updatedLikes = await actions.likePost.orThrow({ postId: post?.id });})</script>ActionErrorCode
Sección titulada “ActionErrorCode”Type: string
Un tipo unión de códigos de estado HTTP estándar definidos por IANA usando las versiones legibles como cadenas en mayúsculas separadas por un guion bajo (ej. BAD_REQUEST o PAYLOAD_TOO_LARGE).
ActionInputSchema
Sección titulada “ActionInputSchema”Type: ZodType
astro@5.16.0
Un tipo utilidad que infiere automáticamente el tipo de TypeScript de la entrada de una action basándose en su esquema Zod. Esto puede ser útil para referenciar el tipo de validador de input de una action como un objeto en tus propias definiciones de tipos.
Devuelve never cuando se omite el validador de input.
El siguiente ejemplo usa ActionInputSchema en una action llamada contact para:
- Obtiene el tipo de esquema Zod para la entrada de la action.
- Obtiene el tipo de entrada esperado del validador de la action.
---import { actions, ActionInputSchema } from 'astro:actions';import { z } from 'astro/zod';
type ContactSchema = ActionInputSchema<typeof actions.contact>;type ContactInput = z.input<ContactSchema>;---ActionReturnType
Sección titulada “ActionReturnType”Type: Awaited<ReturnType<ActionHandler>>
Un tipo utilidad que extrae el tipo de output de un handler de action. Esto desenvuelve tanto la Promise (si el handler es async) como el ReturnType para darte el tipo de output real. Esto puede ser útil si necesitas referenciar el tipo de output de una action en tus propias definiciones de tipos.
El siguiente ejemplo usa ActionReturnType para obtener el tipo de output esperado para una action llamada contact:
---import { actions, ActionReturnType } from 'astro:actions';
type ContactResult = ActionReturnType<typeof actions.contact>;---SafeResult
Sección titulada “SafeResult”Type: { data: TOutput, error: undefined } | { data: undefined, error: ActionError }
Representa el resultado de una llamada a una action:
- en caso de éxito,
datacontiene el output de la action yerroresundefined. - en caso de fallo,
errorcontiene unActionErrorcon errores de validación o errores de runtime, ydataesundefined.