Importer un catalogue de redirections

CloudflareBeginner
Pratiquer maintenant

Introduction

Lorsqu’un site de documentation déplace des pages, les anciens liens doivent continuer à diriger les visiteurs vers le bon emplacement. Une redirection est une réponse HTTP qui demande au navigateur d’utiliser une autre URL. Dans cet atelier, KV contiendra un petit catalogue associant d’anciens chemins à de nouveaux chemins de documentation.

Vous examinerez et validerez un jeu de données JSON fourni avant de l’importer, puis vous lirez le catalogue sur plusieurs pages. La pagination consiste à demander un nombre limité de résultats, puis à utiliser un marqueur de continuation pour récupérer le lot suivant. Enfin, vous modifierez une destination et retirerez deux entrées tout en préservant un enregistrement indépendant dans le même espace de noms. Cette approche est utile lorsque vous gérez une collection de paramètres au lieu de modifier une clé à la fois.

Terminez d’abord les ateliers guidés KV précédents. Cette nouvelle VM contient Node.js 22.22.0 et Wrangler 4.131.1 installé au niveau du projet dans /home/labex/project/redirect-catalog. La configuration fournit cinq redirections synthétiques, mais ne les importe pas et ne crée aucune ressource cloud. Utilisez votre propre compte d’apprentissage avec les mêmes autorisations de lecture du compte, d’écriture sur les Workers et d’écriture sur KV. Un Worker et un espace de noms temporaires suffisent ; aucune mise à niveau payante ni aucun domaine acheté ne sont nécessaires pour ce petit jeu de données. Le catalogue public contient uniquement des chemins d’exemple.

Connecter un espace de noms de redirections

Dans cette étape, vous allez connecter un espace de noms indépendant pour un petit catalogue de redirections. Le binding ROUTES identifiera cet espace de noms pour les opérations en ligne de commande et pour le Worker. Chaque atelier utilise ses propres ressources ; le catalogue ne touchera donc à aucun espace de noms précédent.

Accédez au projet préparé :

cd /home/labex/project/redirect-catalog

Générez une fois un nom unique. openssl rand -hex 6 affiche un suffixe aléatoire ; $(...) l’insère dans le nom. La variable du shell conserve ce nom pour les commandes suivantes dans ce terminal.

WORKER_NAME="labex-routes-$(openssl rand -hex 6)"
printf '%s\n' "$WORKER_NAME"

Autorisez cette VM. En plus de lire l’identité de votre compte, l’autorisation Workers Scripts Write permet le déploiement et la suppression, tandis que Workers KV Write permet de gérer l’espace de noms et les clés de cet atelier.

npx wrangler login --device --browser=false --scopes account:read user:read workers_scripts:write workers_kv:write

Ouvrez dans votre navigateur le lien d’appareil affiché, saisissez le code actuel, vérifiez les autorisations demandées et le compte d’apprentissage, puis autorisez Wrangler. Un accès en arrière-plan peut également apparaître sur la page de consentement. Revenez au terminal et attendez la fin de la connexion.

Vérifiez les mêmes autorisations d’écriture sur le Worker et KV que celles introduites dans Create a Feature Flag Store. Confirmez le compte d’apprentissage avant d’autoriser l’accès.

npx wrangler whoami --json

Vérifiez la présence de loggedIn: true et du name du compte d’apprentissage, même si un seul compte est répertorié. Copiez l’id de ce compte. Enregistrez-le dans la configuration ci-dessous en remplaçant YOUR_ACCOUNT_ID avant d’exécuter la commande. Le here-document cat écrit dans un fichier tout ce qui se trouve entre les deux lignes JSON ; > remplace le fichier. Le délimiteur non placé entre guillemets permet au shell d’insérer $WORKER_NAME.

cat > wrangler.jsonc <<JSON
{
  "name": "$WORKER_NAME",
  "main": "src/index.js",
  "compatibility_date": "2026-07-30",
  "account_id": "YOUR_ACCOUNT_ID",
  "workers_dev": true
}
JSON

Créez un espace de noms dans ce compte. Son titre reprend le nom unique du Worker afin que vous puissiez reconnaître les deux ressources par la suite. --update-config=false laisse la modification du binding visible afin que vous puissiez l’effectuer vous-même, au lieu de modifier automatiquement le fichier.

npx wrangler kv namespace create "$WORKER_NAME-routes" --update-config=false

La sortie contient l’ID du nouvel espace de noms. Copiez-le, puis remplacez YOUR_ACCOUNT_ID et YOUR_NAMESPACE_ID dans cette configuration complète. Le nom du binding ROUTES est choisi pour votre code ; l’ID identifie la ressource Cloudflare réelle.

cat > wrangler.jsonc <<JSON
{
  "name": "$WORKER_NAME",
  "main": "src/index.js",
  "compatibility_date": "2026-07-30",
  "account_id": "YOUR_ACCOUNT_ID",
  "workers_dev": true,
  "kv_namespaces": [
    { "binding": "ROUTES", "id": "YOUR_NAMESPACE_ID" }
  ]
}
JSON
npx wrangler kv namespace list

Repérez le titre de l’espace de noms de cet atelier et comparez son ID avec celui du fichier. D’autres espaces de noms peuvent être présents ; laissez-les inchangés. Cette configuration indique le compte et la ressource que les commandes suivantes doivent utiliser. Un binding est une référence vers un espace de noms, et non une copie de ses données.

Valider et importer un petit catalogue

Dans cette étape, vous allez vérifier un jeu de données avant qu’une commande n’écrive toutes ses entrées. Une opération en masse évite les tâches répétitives, mais reproduit aussi toute erreur dans les données fournies. Commencez par lire le fichier préparé :

cat redirects.json

Chaque objet possède une key telle que route:/old-start et une value telle que /docs/start. Le préfixe route: regroupe les enregistrements du catalogue ; il fait partie de la clé et ne désigne pas un répertoire. La destination est un chemin de ce même site, et non une URL externe quelconque.

Écrivez un script de validation Node.js classique. Il lit un nom de fichier, vérifie le tableau et ses champs, rejette les clés en double et n’affiche le nombre d’entrées qu’après la validation complète. L’objet Set mémorise les clés déjà rencontrées. Les expressions régulières limitent ce jeu de données pédagogique à de simples anciens chemins et destinations de documentation ; il s’agit des règles de cette application, pas de restrictions imposées par KV.

cat > validate-redirects.mjs <<'JS'
import { readFile } from "node:fs/promises";

const filename = process.argv[2] ?? "redirects.json";
const entries = JSON.parse(await readFile(filename, "utf8"));
if (!Array.isArray(entries) || entries.length === 0 || entries.length > 20) {
  throw new Error("Use a non-empty teaching dataset of at most 20 entries.");
}
const seen = new Set();
for (const entry of entries) {
  if (!entry || typeof entry.key !== "string" || !/^route:\/old-[a-z-]+$/.test(entry.key)) {
    throw new Error("Every key must name an old route, such as route:/old-start.");
  }
  if (typeof entry.value !== "string" || !/^\/docs\/[a-z-]+$/.test(entry.value)) {
    throw new Error("Every destination must be a /docs/ path on this site.");
  }
  if (Object.keys(entry).some(key => !["key", "value"].includes(key))) {
    throw new Error("This dataset accepts only key and value fields.");
  }
  if (seen.has(entry.key)) throw new Error(`Duplicate key: ${entry.key}`);
  seen.add(entry.key);
}
console.log(`Validated ${entries.length} unique redirect entries.`);
JS
node validate-redirects.mjs redirects.json

Vous devez obtenir Validated 5 unique redirect entries. Si la validation échoue, corrigez le fichier avant l’importation. Le rejet des clés en double est important, car l’écriture répétée d’une même clé remplace sa valeur.

Créez d’abord localement un élément indépendant du catalogue, puis importez le catalogue. Cet élément vous aidera à vérifier que la maintenance ultérieure du catalogue préserve les autres données.

npx wrangler kv key put system:owner labex-redirect-demo --binding ROUTES --local
npx wrangler kv bulk put redirects.json --binding ROUTES --local
npx wrangler kv key list --binding ROUTES --local

Vous devez obtenir cinq entrées route: ainsi que system:owner. bulk put écrit les entrées du fichier ; il ne remplace pas tout l’espace de noms et ne supprime pas les clés absentes du fichier. Il ne garantit pas non plus une modification atomique visible partout au même instant.

Importez maintenant le même jeu de données vérifié dans l’espace de noms cloud de cet atelier :

npx wrangler kv key put system:owner labex-redirect-demo --binding ROUTES --remote
npx wrangler kv bulk put redirects.json --binding ROUTES --remote
npx wrangler kv key list --binding ROUTES --remote

Vérifiez la présence des six clés. Les options de cible explicites séparent les manipulations locales des écritures cloud. Effectuez le contrôle de cette étape avant de modifier une entrée.

Lire chaque page et servir les redirections

Dans cette étape, vous allez créer un Worker qui répertorie toutes les clés de routes et sert leurs redirections. Un seul appel KV list() peut ne renvoyer qu’une partie d’une collection. Le cursor est un marqueur de continuation fourni par KV ; transmettez-le sans modification pour demander la partie suivante.

Écrivez ce gestionnaire. La valeur volontairement réduite de limit: 2 rend la pagination visible avec seulement cinq enregistrements. En production, le nombre d’éléments par page est généralement plus élevé ; cet atelier limite les données à vingt entrées afin que la boucle reste courte.

cat > src/index.js <<'JS'
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    try {
      if (url.pathname === "/catalog") {
        const names = [];
        let cursor;
        let complete = false;
        let pages = 0;
        do {
          const page = await env.ROUTES.list({ prefix: "route:", limit: 2, cursor });
          names.push(...page.keys.map(key => key.name));
          pages += 1;
          complete = page.list_complete;
          cursor = complete ? undefined : page.cursor;
          if ((!complete && !cursor) || pages > 20) {
            return Response.json({ error: "Catalog could not be completed" }, { status: 503 });
          }
        } while (!complete);
        return Response.json({ keys: names, pages });
      }
      if (url.pathname.startsWith("/docs/")) {
        return new Response(`Example destination: ${url.pathname}`);
      }
      const target = await env.ROUTES.get(`route:${url.pathname}`);
      if (target === null) return new Response("Not found", { status: 404 });
      if (!/^\/docs\/[a-z-]+$/.test(target)) {
        return Response.json({ error: "Invalid redirect destination" }, { status: 500 });
      }
      return Response.redirect(new URL(target, url.origin).href, 302);
    } catch {
      return Response.json({ error: "Redirect storage unavailable" }, { status: 503 });
    }
  }
};
JS

La boucle do...while demande au moins une page et continue jusqu’à ce que list_complete soit défini à true. Elle conserve prefix: "route:" à chaque requête, ce qui empêche l’élément system:owner d’entrer dans le catalogue. names.push(...) ajoute les noms de clés de chaque page au résultat.

Un tableau keys vide ne signifie pas nécessairement que la liste est complète : des entrées supprimées ou arrivées à expiration peuvent laisser une page sans clé renvoyée alors que d’autres pages existent encore. C’est pourquoi la boucle utilise list_complete plutôt que la longueur du tableau. La limite de pages et la vérification d’un curseur manquant produisent une erreur contrôlée si cette démonstration réduite ne peut pas terminer la liste. Consultez KV listing and pagination.

Pour les autres chemins, le Worker lit la clé de route correspondante. Les routes absentes renvoient 404 ; une destination prise en charge produit une réponse 302 avec un en-tête Location. Le runtime vérifie également les destinations afin qu’une valeur KV mal modifiée ne puisse pas rediriger les visiteurs vers un autre site. Les réponses /docs/ sont de simples espaces réservés qui affichent le chemin de destination, et non un site de documentation complet.

npx wrangler dev --local --ip 0.0.0.0 --port 8080 > local.log 2>&1 &
DEV_PID=$!
cat local.log

Attendez le message indiquant que le serveur est prêt, puis inspectez le catalogue complet :

curl -i http://127.0.0.1:8080/catalog

Vous devez obtenir cinq clés de routes triées et au moins trois pages. Des pages supplémentaires vides sont possibles ; le résultat important est l’ensemble complet des clés, sans entrée system:owner.

curl -i http://127.0.0.1:8080/old-start

Vous devez obtenir le code HTTP 302 et Location: http://127.0.0.1:8080/docs/start. Par défaut, curl affiche la réponse de redirection sans la suivre. Conservez le jeu de données local inchangé pour pouvoir le comparer plus tard.

Mettre à jour certaines routes et préserver les autres données

Dans cette étape, vous allez modifier le catalogue cloud sans remplacer son espace de noms. La nouvelle page de démarrage est /docs/getting-started, tandis que deux pages temporaires ne doivent plus rediriger.

npx wrangler kv key put route:/old-start /docs/getting-started --binding ROUTES --remote

L’écriture d’une clé sélectionnée laisse les autres routes inchangées. Pour supprimer plusieurs clés, Wrangler accepte un tableau JSON contenant leurs noms exacts. Lisez cette petite liste de retrait avant d’exécuter la suppression :

cat > retired-keys.json <<'JSON'
["route:/old-contact", "route:/old-event"]
JSON
cat retired-keys.json
npx wrangler kv bulk delete retired-keys.json --binding ROUTES --remote

Si une confirmation vous est demandée, vérifiez que le binding et l’opération indiquée concernent l’espace de noms temporaire de cet atelier. La liste contient uniquement deux clés de routes ; elle ne contient pas system:owner.

npx wrangler kv key list --binding ROUTES --remote
npx wrangler kv key get system:owner --binding ROUTES --remote --text

Vous devez obtenir trois routes restantes et la valeur inchangée labex-redirect-demo. Ne relancez pas l’importation en masse d’origine : ses anciennes valeurs annuleraient la mise à jour et restaureraient les clés retirées.

Déployez le Worker, confirmez le binding ROUTES et copiez son adresse publique réelle :

npx wrangler deploy
WORKER_URL="https://YOUR_WORKER.YOUR_SUBDOMAIN.workers.dev"
curl -i "$WORKER_URL/catalog"

Vérifiez d’abord que /catalog renvoie HTTP 200 et les clés JSON attendues. Si une page d’erreur Cloudflare apparaît, attendez un peu et répétez les requêtes en lecture seule. Une route retirée est correcte uniquement si elle renvoie HTTP 404 avec le corps applicatif Not found ; le code de statut seul ne suffit pas.

Le catalogue doit contenir uniquement route:/old-pricing, route:/old-start et route:/old-support. Testez les chemins modifié et retirés :

curl -i "$WORKER_URL/old-start"
curl -i "$WORKER_URL/old-contact"
curl -i "$WORKER_URL/old-event"

Le chemin de démarrage doit rediriger vers /docs/getting-started ; les deux chemins retirés doivent renvoyer 404. Si les nouvelles données cloud ne sont pas encore visibles, attendez la propagation de KV et réessayez les contrôles en lecture seule. Une erreur de connexion ne constitue pas un résultat de retrait réussi.

curl -i http://127.0.0.1:8080/catalog

Le développement local répertorie toujours les cinq routes d’origine. Cette différence confirme que les commandes de maintenance ont ciblé le stockage cloud. Dans le Dashboard, sélectionnez le même compte, ouvrez Storage & databases → Workers KV, puis inspectez l’espace de noms de cet atelier. Comparez ses trois entrées de routes et l’élément propriétaire conservé avec la sortie des commandes. Ce point de contrôle est en lecture seule ; le nom et l’ID générés pour votre espace de noms sont propres à cette exécution.

Sélectionnez KV Pairs pour afficher les enregistrements ci-dessous. Utilisez Refresh si vous avez ouvert l’espace de noms avant la fin des commandes de maintenance.

Trois routes conservées et l’enregistrement propriétaire inchangé

Supprimer les ressources cloud temporaires

Dans cette étape, vous allez supprimer les deux ressources pendant que Wrangler est encore autorisé. Un espace de noms peut rester après la suppression de son Worker ; supprimer uniquement l’application ne supprime donc pas ses données.

Arrêtez le processus de développement local démarré dans ce terminal :

kill "$DEV_PID"

Examinez les références de ressources enregistrées avant toute suppression :

cat wrangler.jsonc

Vérifiez le nom du Worker labex-routes-... et l’ID de l’espace de noms ROUTES. Supprimez le Worker sélectionné par cette configuration :

npx wrangler delete

Si une confirmation vous est demandée, vérifiez que le nom affiché correspond à cet atelier et confirmez avec y. Supprimez ensuite uniquement l’espace de noms référencé par ROUTES :

npx wrangler kv namespace delete --binding ROUTES

Examinez l’espace de noms dans toute demande de confirmation avant de l’accepter. Conservez wrangler.jsonc intact afin que la vérification indépendante puisse identifier les ressources qui doivent avoir disparu.

npx wrangler kv namespace list

L’espace de noms de cet atelier doit avoir disparu ; les espaces de noms indépendants doivent rester présents. Actualisez les listes du Dashboard pour confirmer la disparition du Worker et de l’espace de noms de l’atelier. Une requête échouée ou une connexion expirée ne prouve pas la suppression. Effectuez le contrôle de cette étape avant de vous déconnecter afin qu’il puisse inspecter un inventaire autorisé.

Mettre fin à l’autorisation de la VM

Dans cette étape, vous allez déconnecter Wrangler une fois le contrôle du nettoyage terminé. La déconnexion met fin à l’autorisation Wrangler enregistrée sur cette VM ; elle ne supprime pas les ressources cloud et ne vous déconnecte pas de votre session habituelle du Dashboard dans le navigateur.

npx wrangler logout
npx wrangler whoami --json

Vérifiez que le résultat structuré indique "loggedIn": false. Cette commande non authentifiée peut se terminer avec un code de sortie différent de zéro, ce qui est attendu ici. Si vous n’obtenez qu’une erreur de connexion sans état d’authentification explicite, réessayez lorsque la connexion fonctionnera.

Les fichiers locaux restants et l’état KV local appartiennent à cette VM temporaire. Ils sont indépendants des ressources cloud que vous avez déjà supprimées. Vous pouvez maintenant terminer l’atelier.

Résumé

Vous avez validé un petit jeu de données de redirections avant une écriture en masse, gardé explicites les cibles locales et cloud, puis parcouru toutes les pages d’une liste KV utilisant un préfixe. Vous avez modifié une route et retiré deux clés précises tout en préservant un enregistrement propriétaire indépendant. Les réponses du Worker déployé ont confirmé la nouvelle destination et l’absence des routes retirées, tandis que le catalogue local a conservé ses données d’origine.

Enfin, vous avez supprimé le Worker et l’espace de noms temporaires, puis vous vous êtes déconnecté. Ensuite, vous étudierez les lectures de configuration qui peuvent temporairement renvoyer une version antérieure.