Actions
Ajouté à la version :
astro@4.15
Astro Actions vous permet de définir et d’appeler des fonctions backend avec sûreté du typage. Les actions effectuent la récupération des données, l’analyse JSON et la validation des entrées pour vous. Cela peut réduire considérablement la quantité de code standard nécessaire par rapport à l’utilisation d’un point de terminaison d’API.
Utilisez des actions à la place de points de terminaison d’API pour une communication transparente entre votre code client et votre code serveur et pour :
- Valider automatiquement les entrées de données JSON et de formulaire à l’aide de la validation Zod.
- Générer des fonctions avec sûreté du typage pour appeler votre backend à partir du client et même à partir des actions de formulaire HTML. Pas besoin d’appels manuels à
fetch()
. - Standardiser les erreurs du backend avec l’objet
ActionError
.
Utilisation de base
Titre de la section Utilisation de baseLes actions sont définies dans un objet server
exporté depuis src/actions/index.ts
:
Vos actions sont disponibles en tant que fonctions à partir du module astro:actions
. Importez actions
et appelez-les côté client dans un composant de framework UI, une requête POST de formulaire ou en utilisant une balise <script>
dans un composant Astro.
Lorsque vous appelez une action, elle renvoie un objet avec soit data
contenant le résultat sérialisé JSON, soit error
contenant les erreurs renvoyées.
Écrivez votre première action
Titre de la section Écrivez votre première actionSuivez ces étapes pour définir une action et pour l’appeler dans une balise script
de votre page Astro.
-
Créez un fichier
src/actions/index.ts
et exportez un objetserver
. -
Importez l’utilitaire
defineAction()
depuisastro:actions
et l’objetz
depuisastro:schema
. -
Utilisez l’utilitaire
defineAction()
pour définir une actiongetGreeting
. La propriétéinput
sera utilisée pour valider les paramètres d’entrée avec un schéma Zod et la fonctionhandler()
inclut la logique backend à exécuter sur le serveur. -
Créez un composant Astro avec un bouton qui récupérera un message d’accueil à l’aide de votre action
getGreeting
lorsqu’il est cliqué. -
Pour utiliser votre action, importez
actions
depuisastro:actions
puis appelezactions.getGreeting()
dans le gestionnaire de clics. L’optionname
sera envoyée à la fonctionhandler()
de votre action sur le serveur et, s’il n’y a pas d’erreur, le résultat sera disponible sous la forme de la propriétédata
.
defineAction()
et ses propriétés.
Organiser les actions
Titre de la section Organiser les actionsToutes les actions de votre projet doivent être exportées depuis l’objet server
dans le fichier src/actions/index.ts
. Vous pouvez définir des actions en ligne ou déplacer les définitions d’actions vers des fichiers séparés et les importer. Vous pouvez même regrouper des fonctions liées dans des objets imbriqués.
Par exemple, pour regrouper toutes vos actions utilisateur, vous pouvez créer un fichier src/actions/user.ts
et imbriquer les définitions de getUser
et createUser
dans un seul objet user
.
Ensuite, vous pouvez importer cet objet user
dans votre fichier src/actions/index.ts
et l’ajouter en tant que propriété de niveau supérieur à l’objet server
aux côtés de toute autre action :
Désormais, toutes vos actions utilisateur peuvent être appelées à partir de l’objet actions.user
:
actions.user.getUser()
actions.user.createUser()
Gestion des données renvoyées
Titre de la section Gestion des données renvoyéesLes actions renvoient un objet contenant soit data
qui contient la valeur de retour de votre fonction handler()
avec sûreté du typage, soit error
qui contient les erreurs du backend. Ces dernières peuvent provenir d’erreurs de validation sur la propriété input
ou d’erreurs générées dans la fonction handler()
.
Les actions renvoient un format de données personnalisé qui peut gérer les Dates, les Maps, les Sets et les URL à l’aide de la bibliothèque Devalue. Par conséquent, vous ne pouvez pas facilement inspecter la réponse du réseau comme vous le pouvez avec du JSON classique. Pour le débogage, vous pouvez plutôt inspecter l’objet data
renvoyé par les actions.
handler()
pour plus de détails.
Vérification des erreurs
Titre de la section Vérification des erreursIl est préférable de vérifier si une erreur (error
) est présente avant d’utiliser la propriété data
. Cela vous permet à la fois de gérer les erreurs à l’avance et d’être certain que data
est définie sans vérification additionnelle pour undefined
.
Accéder directement aux données sans vérification d’erreur
Titre de la section Accéder directement aux données sans vérification d’erreurPour ignorer la gestion des erreurs, par exemple lors du prototypage ou de l’utilisation d’une bibliothèque qui détectera les erreurs à votre place, utilisez la propriété .orThrow()
sur votre appel d’action pour générer des erreurs au lieu de renvoyer une error
. Cela renverra directement les data
de l’action.
Cet exemple appelle une action likePost()
qui renvoie le nombre mis à jour de mentions « j’aime » sous forme de nombre à partir de l’action handler
:
Gestion des erreurs backend dans votre action
Titre de la section Gestion des erreurs backend dans votre actionVous pouvez utiliser la classe ActionError
fournie pour générer une erreur à partir de la fonction handler()
de votre action, comme, par exemple, « not found » lorsqu’une entrée de base de données est manquante ou « unauthorized » lorsqu’un utilisateur n’est pas connecté. Cela présente deux avantages principaux par rapport au renvoi de undefined
:
-
Vous pouvez définir un code d’état tel que
404 - Not found
ou401 - Unauthorized
. Cela améliore le débogage des erreurs à la fois en développement et en production en vous permettant de voir le code d’état de chaque demande. -
Dans le code de votre application, toutes les erreurs sont transmises à l’objet
error
sur un résultat d’action. Cela évite d’avoir à vérifier si les données sont indéfinies et vous permet d’afficher des commentaires ciblés à l’utilisateur en fonction de ce qui s’est mal passé.
Création d’une ActionError
Titre de la section Création d’une ActionErrorPour générer une erreur, importez la classe ActionError()
depuis le module astro:actions
. Transmettez-lui un code d’état lisible par l’homme (par exemple "NOT_FOUND"
ou "BAD_REQUEST"
), et un message
facultatif pour fournir des informations supplémentaires sur l’erreur.
Cet exemple génère une erreur d’une action likePost
lorsqu’un utilisateur n’est pas connecté, après avoir vérifié un hypothétique cookie de « session utilisateur » pour l’authentification :
Gestion d’une ActionError
Titre de la section Gestion d’une ActionErrorPour gérer cette erreur, vous pouvez appeler l’action depuis votre application et vérifier si une propriété error
est présente. Cette propriété sera de type ActionError
et contiendra votre code
et message
.
Dans l’exemple suivant, un composant LikeButton.tsx
appelle l’action likePost()
lorsqu’il est cliqué. Si une erreur d’authentification se produit, l’attribut error.code
est utilisé pour déterminer s’il faut afficher un lien de connexion :
Gestion des redirections client
Titre de la section Gestion des redirections clientLorsque vous appelez des actions à partir du client, vous pouvez intégrer une bibliothèque côté client comme react-router
, ou vous pouvez utiliser la fonction navigate()
d’Astro pour rediriger vers une nouvelle page lorsqu’une action réussit.
Cet exemple permet de retourner sur la page d’accueil après qu’une action de déconnexion (logout
) ait abouti avec succès :
Accepter les données d’un formulaire à partir d’une action
Titre de la section Accepter les données d’un formulaire à partir d’une actionLes actions acceptent les données JSON par défaut. Pour accepter les données d’un formulaire HTML, définissez accept: 'form'
dans votre appel defineAction()
:
Validation des données du formulaire
Titre de la section Validation des données du formulaireLes actions analyseront les données de formulaire soumises à un objet, en utilisant la valeur de l’attribut name
de chaque entrée comme propriétés d’objet. Par exemple, un formulaire contenant <input name="search">
sera analysé en un objet comme { search: 'user input' }
. Le schéma input
de votre action sera utilisé pour valider cet objet.
Pour recevoir l’objet FormData
brut dans votre gestionnaire d’action au lieu d’un objet analysé, omettez la propriété input
dans la définition de votre action.
L’exemple suivant montre un formulaire d’inscription à une newsletter validé qui accepte l’e-mail d’un utilisateur et nécessite une case à cocher pour accepter les « conditions d’utilisation ».
-
Créez un composant de formulaire HTML avec des attributs
name
uniques sur chaque entrée : -
Définir une action
newsletter
pour gérer le formulaire soumis. Validez le champemail
en utilisant le validateurz.string().email()
et la case à cocherterms
en utilisantz.boolean()
:Consultez la référence de l’APIinput
pour tous les validateurs de formulaire disponibles. -
Ajoutez un
<script>
au formulaire HTML pour soumettre la saisie de l’utilisateur. Cet exemple remplace le comportement de soumission par défaut du formulaire pour appeleractions.newsletter()
et redirige vers/confirmation
à l’aide de la fonctionnavigate()
:Consultez « Appeler des actions depuis une action de formulaire HTML » pour découvrir une autre façon de soumettre des données de formulaire.
Affichage des erreurs de saisie du formulaire
Titre de la section Affichage des erreurs de saisie du formulaireVous pouvez valider les entrées du formulaire avant la soumission à l’aide des attributs natifs de validation de formulaire HTML tels que required
, type="email"
et pattern
. Pour une validation plus complexe d’input
depuis le backend, vous pouvez utiliser la fonction utilitaire isInputError()
.
Pour récupérer les erreurs de saisie, utilisez l’utilitaire isInputError()
pour vérifier si une erreur a été provoquée par une entrée non valide. Les erreurs de saisie contiennent un objet fields
avec des messages pour chaque nom d’entrée qui n’a pas pu être validé. Vous pouvez utiliser ces messages pour demander à votre utilisateur de corriger sa soumission.
L’exemple suivant vérifie l’erreur avec isInputError()
, puis vérifie si l’erreur se trouve dans le champ e-mail, avant de créer finalement un message à partir des erreurs. Vous pouvez utiliser la manipulation DOM JavaScript ou votre infrastructure d’interface utilisateur préférée pour afficher ce message aux utilisateurs.
Appeler des actions depuis une action de formulaire HTML
Titre de la section Appeler des actions depuis une action de formulaire HTMLLes pages doivent être rendues à la demande lors de l’appel d’actions à l’aide d’une action de formulaire. Assurez-vous que le prérendu est désactivé sur la page (EN) avant d’utiliser cette API.
Vous pouvez activer les soumissions de formulaires zéro-JS avec des attributs standard sur n’importe quel élément <form>
. Les soumissions de formulaires sans JavaScript côté client peuvent être utiles à la fois comme solution de secours en cas d’échec du chargement de JavaScript ou si vous préférez gérer les formulaires entièrement à partir du serveur.
L’appel de Astro.getActionResult() sur le serveur renvoie le résultat de votre soumission de formulaire (data
ou error
), et peut être utilisé pour rediriger dynamiquement, gérer les erreurs de formulaire, mettre à jour l’interface utilisateur, etc.
Pour appeler une action à partir d’un formulaire HTML, ajoutez method="POST"
à votre <form>
, puis définissez l’attribut action
du formulaire à l’aide de votre action, par exemple action={actions.logout}
. Cela définira l’attribut action
pour utiliser une chaîne de requête gérée automatiquement par le serveur.
Par exemple, ce composant Astro appelle l’action logout
lorsque le bouton est cliqué et recharge la page actuelle :
Redirection en cas de réussite de l’action
Titre de la section Redirection en cas de réussite de l’actionSi vous devez rediriger vers une nouvelle route en cas de succès, vous pouvez utiliser le résultat d’une action sur le serveur. Un exemple courant est la création d’un enregistrement de produit et la redirection vers la page du nouveau produit, par exemple /products/[id]
.
Par exemple, supposons que vous ayez une action createProduct
qui renvoie l’identifiant du produit généré :
Vous pouvez récupérer le résultat de l’action de votre composant Astro en appelant Astro.getActionResult()
. Cela renvoie un objet contenant les propriétés data
ou error
lorsqu’une action est appelée, ou undefined
si l’action n’a pas été appelée pendant cette requête.
Utilisez la propriété data
pour construire une URL à utiliser avec Astro.redirect()
:
Gérer les erreurs d’action du formulaire
Titre de la section Gérer les erreurs d’action du formulaireL’appel de Astro.getActionResult()
dans le composant Astro contenant votre formulaire vous donne accès aux objets data
et error
pour la gestion personnalisée des erreurs.
L’exemple suivant affiche un message d’échec général lorsqu’une action newsletter
échoue :
Pour plus de personnalisation, vous pouvez utiliser l’utilitaire isInputError()
pour vérifier si une erreur est provoquée par une entrée non valide.
L’exemple suivant affiche une bannière d’erreur sous le champ de saisie email
lorsqu’un e-mail invalide est soumis :
Conserver les valeurs d’entrée en cas d’erreur
Titre de la section Conserver les valeurs d’entrée en cas d’erreurLes entrées seront effacées à chaque fois qu’un formulaire sera soumis. Pour conserver les valeurs d’entrée, vous pouvez activer les transitions de vue sur la page et appliquer la directive transition:persist
à chaque entrée :
Mettre à jour l’interface utilisateur avec un résultat d’action de formulaire
Titre de la section Mettre à jour l’interface utilisateur avec un résultat d’action de formulairePour utiliser la valeur de retour d’une action pour afficher une notification à l’utilisateur en cas de réussite, transmettez l’action à Astro.getActionResult()
. Utilisez la propriété data
renvoyée pour restituer l’interface utilisateur que vous souhaitez afficher.
Cet exemple utilise la propriété productName
renvoyée par une action addToCart
pour afficher un message de réussite.
Avancé : Persistance des résultats d’action avec une session
Titre de la section Avancé : Persistance des résultats d’action avec une session
Ajouté à la version :
astro@5.0.0
Nouveau
Les résultats de l’action sont affichés sous forme de soumission POST. Cela signifie que le résultat sera réinitialisé sur undefined
lorsqu’un utilisateur fermera et revisitera la page. L’utilisateur verra également une boîte de dialogue « Confirmer la nouvelle soumission du formulaire ?» s’il tente d’actualiser la page.
Pour personnaliser ce comportement, vous pouvez ajouter un middleware pour gérer manuellement le résultat de l’action. Vous pouvez choisir de conserver le résultat de l’action à l’aide d’un cookie ou d’un stockage de session.
Commencez par créer un fichier middleware et par importer l’utilitaire getActionContext()
depuis astro:actions
. Cette fonction renvoie un objet action
avec des informations sur la demande d’action entrante, y compris le gestionnaire d’action et si l’action a été appelée à partir d’un formulaire HTML. getActionContext()
renvoie également les fonctions setActionResult()
et serializeActionResult()
pour définir par programmation la valeur renvoyée par Astro.getActionResult()
:
Une pratique courante pour conserver les résultats des formulaires HTML est le modèle POST / Redirect / GET. Cette redirection supprime la boîte de dialogue « Confirmer la nouvelle soumission du formulaire ?» lorsque la page est actualisée et permet aux résultats de l’action d’être conservés tout au long de la session de l’utilisateur.
Cet exemple applique le modèle POST / Redirect / GET à toutes les soumissions de formulaire utilisant le stockage de session avec l’adaptateur de serveur Netlify installé. Les résultats de l’action sont écrits dans un magasin de sessions à l’aide de Netlify Blob et récupérés après une redirection à l’aide d’un ID de session :
Sécurité lors de l’utilisation des actions
Titre de la section Sécurité lors de l’utilisation des actionsLes actions sont accessibles en tant que points de terminaison publics en fonction du nom de l’action. Par exemple, l’action blog.like()
sera accessible depuis /_actions/blog.like
. Cela est utile pour tester les résultats des actions et déboguer les erreurs de production. Cependant, cela signifie que vous devez utiliser les mêmes contrôles d’autorisation que ceux que vous envisageriez pour les points de terminaison d’API et les pages rendues à la demande.
Autoriser les utilisateurs à partir d’un gestionnaire d’actions
Titre de la section Autoriser les utilisateurs à partir d’un gestionnaire d’actionsPour autoriser les demandes d’action, ajoutez une vérification d’authentification à votre gestionnaire d’actions. Vous souhaiterez peut-être utiliser une bibliothèque d’authentification pour gérer la gestion des sessions et les informations utilisateur.
Les actions exposent l’objet APIContext
complet pour accéder aux propriétés transmises par le middleware à l’aide de context.locals
. Lorsqu’un utilisateur n’est pas autorisé, vous pouvez générer une ActionError
avec le code UNAUTHORIZED
:
Limiter les actions depuis le middleware
Titre de la section Limiter les actions depuis le middleware
Ajouté à la version :
astro@5.0.0
Nouveau
Astro recommande d’autoriser les sessions utilisateur à partir de votre gestionnaire d’actions pour respecter les niveaux d’autorisation et la limitation de débit par action. Cependant, vous pouvez également limiter les demandes à toutes les actions (ou à un sous-ensemble d’actions) à partir du middleware.
Utilisez la fonction getActionContext()
de votre middleware pour récupérer des informations sur les demandes d’action entrantes. Cela inclut le nom de l’action et si cette action a été appelée à l’aide d’une fonction d’appel de procédure à distance (RPC) côté client (par exemple, actions.blog.like()
) ou d’un formulaire HTML.
L’exemple suivant rejette toutes les demandes d’action qui ne disposent pas d’un jeton de session valide. Si la vérification échoue, une réponse « Interdit » est renvoyée. Remarque : cette méthode garantit que les actions ne sont accessibles que lorsqu’une session est présente, mais ne remplace pas une autorisation sécurisée.
Appeler des actions à partir des composants Astro et des points de terminaison du serveur
Titre de la section Appeler des actions à partir des composants Astro et des points de terminaison du serveurVous pouvez appeler des actions directement à partir des scripts de composants Astro en utilisant l’enveloppe Astro.callAction()
(ou context.callAction()
lors de l’utilisation d’un point de terminaison de serveur). Il est courant de réutiliser la logique de vos actions dans un autre code serveur.
Transmettez l’action comme premier argument et tous les paramètres d’entrée comme deuxième argument. Cela renvoie les mêmes objets data
et error
que vous recevez lors de l’appel d’actions sur le client :