Créer une couche d’accès aux données
Objectif : Écrire une fonction serveur qui récupère les randonnées depuis une API et vérifie la réponse avant d’utiliser les données.
Une page de catalogue ne doit pas mélanger l’affichage et les détails de la requête qui fournit ses données. En centralisant cette requête dans une fonction, vous pouvez contrôler la réponse HTTP à un seul endroit et fournir à la page une liste cohérente de randonnées.
Dans cette leçon, la fonction d’accès aux données est placée dans app/page.tsx, afin de respecter les fichiers prévus pour le projet. Elle reste donc associée à la page catalogue et s’exécute côté serveur. Vous avez déjà vu ce mode d’exécution dans la leçon « Repérer les composants serveur dans l’App Router » ; vous n’avez pas besoin de déplacer la requête vers le navigateur.
Définir une source de données côté serveur
L’exemple utilise une API qui renvoie les randonnées au format JSON. Son adresse est configurée dans la variable d’environnement serveur CATALOGUE_API_URL, par exemple https://api.exemple.test. Configurez cette valeur dans l’environnement de votre application, sans la préfixer par NEXT_PUBLIC_ : l’adresse et les éventuels identifiants associés ne doivent pas être transmis au navigateur.
Pour que la suite de l’exemple puisse afficher chaque carte, l’API fournit un tableau d’objets contenant id, nom, difficulte et distance. Ces propriétés sont décrites par le type TypeScript Randonnee. Le type documente les données attendues pendant le développement ; il ne remplace pas la vérification du statut de la réponse HTTP.
Écrire la fonction et l’utiliser dans la page
Le fichier ci-dessous est complet pour l’état de cette leçon. La fonction obtenirRandonnees construit l’URL de la ressource, exécute une requête HTTP avec fetch, puis vérifie response.ok. Une réponse dont le statut indique un échec provoque une exception explicite ; le code ne tente pas de lire son corps comme s’il s’agissait d’une liste.
import 'server-only';
type Randonnee = {
id: string;
nom: string;
difficulte: string;
distance: number;
};
async function obtenirRandonnees(): Promise<Randonnee[]> {
const baseUrl = process.env.CATALOGUE_API_URL;
if (!baseUrl) {
throw new Error('La variable CATALOGUE_API_URL est absente.');
}
const response = await fetch(`${baseUrl}/randonnees`);
if (!response.ok) {
throw new Error(
`La récupération des randonnées a échoué (HTTP ${response.status}).`
);
}
const randonnees = await response.json() as Randonnee[];
return randonnees;
}
export default async function CataloguePage() {
const randonnees = await obtenirRandonnees();
return (
<>
<h1 className="rando-titre">Randonnées à découvrir</h1>
{randonnees.length === 0 ? (
<p className="rando-etat" role="status">
Aucune randonnée n’est disponible.
</p>
) : (
<ul className="rando-liste">
{randonnees.map((randonnee) => (
<li className="rando-carte" key={randonnee.id}>
<a href={`/randonnees/${randonnee.id}`}>
<h2>{randonnee.nom}</h2>
<p>{randonnee.difficulte} · {randonnee.distance} km</p>
</a>
</li>
))}
</ul>
)}
</>
);
}L’import server-only marque le fichier comme réservé au serveur : une tentative de l’importer depuis un composant client déclenchera une erreur de compilation. Cette protection, abordée dans la leçon sur les secrets, est importante ici puisque la fonction lit une variable d’environnement et appelle une API. La page utilise ensuite le résultat pour construire les cartes ; aucune clé ni réponse brute n’est envoyée à un composant client.
Vérifier le résultat de la requête
Avec une réponse HTTP réussie contenant deux randonnées, la page rend deux cartes avec leur nom, leur difficulté et leur distance. Avec un tableau JSON vide, elle affiche « Aucune randonnée n’est disponible ». Si l’API répond par exemple avec le statut 503, la fonction s’arrête sur l’exception et ne produit pas un faux état vide.
Vérifiez que l’URL configurée pointe vers la ressource /randonnees et que l’API renvoie bien le tableau attendu. Pour l’instant, la fonction ne passe aucun critère de recherche et ne fixe pas de durée de cache. Le filtrage sera ajouté dans la prochaine leçon ; la stratégie de mise en cache sera étudiée ensuite.
À retenir
- Centralisez la requête du catalogue dans une fonction d’accès aux données côté serveur.
- Lisez l’adresse de l’API depuis une variable d’environnement serveur.
- Vérifiez response.ok avant de lire le JSON et signalez les statuts HTTP en échec.
- Gardez distincts une liste vide et une requête qui a échoué.