Écrire l’avis dans la base
Objectif : Enregistrer un avis validé en l’associant à la randonnée concernée.
Un commentaire peut être correctement saisi et validé sans avoir encore été enregistré. Dans cette leçon, vous complétez l’action serveur pour envoyer l’avis au service qui écrit dans la base, en conservant l’identifiant de la randonnée concernée.
La validation de FormData et la normalisation du commentaire ont déjà été traitées dans la leçon précédente. Ici, vous ajoutez l’écriture après ces contrôles : une donnée invalide ne doit jamais déclencher de requête d’insertion.
Définir l’écriture côté serveur
L’exemple ci-dessous envoie l’avis à un service HTTP privé, configuré avec RANDONNEES_API_URL. Ce service représente la couche serveur reliée à votre base : il reçoit une requête POST contenant l’identifiant de randonnée et le texte validé. Il doit refuser les identifiants inconnus et répondre avec un statut HTTP d’échec si l’insertion ne peut pas être effectuée.
'use server';
import { revalidatePath } from 'next/cache';
export async function ajouterAvis(formData: FormData) {
const randonneeId = formData.get('randonneeId');
const texteRecu = formData.get('texte');
if (typeof randonneeId !== 'string' || typeof texteRecu !== 'string') {
throw new Error('Les données de l’avis sont invalides.');
}
const texte = texteRecu.trim();
if (!randonneeId || texte.length === 0 || texte.length > 1000) {
throw new Error('Les données de l’avis sont invalides.');
}
const apiUrl = process.env.RANDONNEES_API_URL;
if (!apiUrl) {
throw new Error('Le service d’écriture des avis n’est pas configuré.');
}
let response: Response;
try {
response = await fetch(`${apiUrl}/randonnees/${encodeURIComponent(randonneeId)}/avis`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ texte }),
cache: 'no-store'
});
} catch {
throw new Error('Impossible de joindre le service d’écriture des avis.');
}
if (!response.ok) {
throw new Error('L’avis n’a pas pu être enregistré.');
}
}L’action est asynchrone : elle attend la réponse du service avant de se terminer. Elle n’envoie que le texte dans le corps JSON ; l’identifiant est transmis dans le chemin de la requête afin que le service rattache l’avis à la bonne randonnée. Le service doit contrôler que cette randonnée existe avant d’insérer l’enregistrement.
Distinguer écriture réussie et échec
Une réponse HTTP dont le statut n’est pas réussi déclenche une erreur : une panne ou un refus d’insertion ne peut donc pas être interprété comme une écriture accomplie. La requête est également protégée contre les erreurs réseau et l’absence de configuration. Ces erreurs remontent à Next.js au lieu d’être masquées par un faux succès.
Le contrat suppose que le service accepte un POST sur /randonnees/{id}/avis et renvoie un statut de succès après l’insertion. Adaptez cette URL au contrat réel de votre API, sans déplacer l’appel dans le composant de page ou dans le navigateur. La clé d’accès, si elle est nécessaire, doit être ajoutée à cette requête côté serveur depuis une variable d’environnement privée.
Relier l’action au formulaire existant
La fiche continue d’utiliser action={ajouterAvis} sur son formulaire, avec les champs randonneeId et texte déjà en place. Vous n’avez pas à ajouter de gestionnaire client ni à exposer l’URL du service au navigateur : Next.js appelle cette fonction sur le serveur lors de la soumission.
À ce stade, l’action confirme l’écriture en se terminant sans erreur, mais elle ne demande pas encore à Next.js de rafraîchir les données affichées. La revalidation après écriture, avec revalidatePath, appartient à la prochaine leçon ; n’ajoutez pas ici de mécanisme de mise à jour du cache.
À retenir
- Effectuez l’insertion dans une action serveur asynchrone, après validation des champs.
- Transmettez l’identifiant de randonnée et le texte validé au service privé chargé de l’écriture.
- Vérifiez le statut de la réponse et laissez remonter les erreurs réseau ou d’insertion.
- La mise à jour du cache après l’écriture sera ajoutée dans la leçon suivante.