Introducción
Cuando un sitio de documentación cambia de ubicación sus páginas, los enlaces antiguos deben seguir llevando a los visitantes al lugar correcto. Una redirección es una respuesta HTTP que indica al navegador que solicite una URL diferente. En este laboratorio, KV almacenará un catálogo pequeño que relaciona rutas antiguas con nuevas rutas de documentación.
Primero inspeccionará y validará un conjunto de datos JSON proporcionado antes de importarlo; después, leerá el catálogo en varias páginas. La paginación consiste en solicitar un lote limitado de resultados y usar un marcador de continuación para obtener el lote siguiente. Por último, cambiará un destino y retirará dos entradas, mientras conserva un registro no relacionado en el mismo espacio de nombres. Esto resulta útil cuando mantiene una colección de configuraciones en lugar de editar una clave cada vez.
Complete primero los laboratorios guiados anteriores de KV. Esta VM nueva incluye Node.js 22.22.0 y Wrangler 4.131.1 instalado localmente en el proyecto, ubicado en /home/labex/project/redirect-catalog. La configuración inicial proporciona cinco redirecciones sintéticas, pero no las importa ni crea recursos en la nube. Use su propia cuenta de aprendizaje con los mismos permisos de lectura de cuenta, escritura de Workers y escritura de KV. Un Worker y un espacio de nombres desechables son suficientes; no necesita una actualización de pago ni comprar un dominio para este conjunto de datos pequeño. El catálogo público contiene únicamente rutas de ejemplo.
Conectar un espacio de nombres de redirecciones
En este paso, conectará un espacio de nombres independiente para un catálogo pequeño de redirecciones. El binding ROUTES identificará este espacio de nombres tanto para las operaciones de la línea de comandos como para el Worker. Cada laboratorio comienza con sus propios recursos, por lo que el catálogo no afectará a ningún espacio de nombres anterior.
Entre en el proyecto preparado:
cd /home/labex/project/redirect-catalog
Genere un nombre único una sola vez. openssl rand -hex 6 muestra un sufijo aleatorio; $(...) lo inserta en el nombre. La variable de shell conservará ese nombre para los comandos siguientes en este terminal.
WORKER_NAME="labex-routes-$(openssl rand -hex 6)"
printf '%s\n' "$WORKER_NAME"
Autorice esta VM. Además de leer la identidad de su cuenta, Workers Scripts Write permite implementar y eliminar recursos, y Workers KV Write permite administrar el espacio de nombres y las claves de este laboratorio.
npx wrangler login --device --browser=false --scopes account:read user:read workers_scripts:write workers_kv:write
Abra en el navegador el enlace de dispositivo que se muestra, introduzca el código actual, revise los permisos solicitados y la cuenta de aprendizaje, y autorice Wrangler. En la página de consentimiento también puede aparecer el acceso en segundo plano. Vuelva al terminal y espere a que finalice el inicio de sesión.
Revise los mismos permisos de escritura de Workers y KV que se introdujeron en Create a Feature Flag Store. Confirme la cuenta de aprendizaje antes de autorizarla.
npx wrangler whoami --json
Confirme loggedIn: true y el name de la cuenta de aprendizaje, aunque solo aparezca una cuenta. Copie el id de esa cuenta. Guárdelo en la configuración siguiente y reemplace YOUR_ACCOUNT_ID antes de ejecutar el comando. El documento here-document de cat escribe en un archivo todo lo que se encuentra entre las dos líneas JSON; > reemplaza el archivo. El delimitador sin comillas permite que el shell sustituya $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
Cree un espacio de nombres en esa cuenta. Su título comparte el nombre único del Worker para que pueda reconocer ambos recursos más adelante. --update-config=false mantiene visible para usted la edición del binding, en lugar de modificar automáticamente el archivo.
npx wrangler kv namespace create "$WORKER_NAME-routes" --update-config=false
La salida incluye el ID del nuevo espacio de nombres. Cópielo y, después, reemplace YOUR_ACCOUNT_ID y YOUR_NAMESPACE_ID en esta configuración completa. El nombre del binding ROUTES se utiliza en su código; el ID identifica el recurso real de Cloudflare.
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
Busque el título del espacio de nombres de este laboratorio y compare su ID con el del archivo. Puede haber otros espacios de nombres; no los modifique. Esta configuración registra qué cuenta y qué recurso deben utilizar los comandos posteriores. Un binding es una referencia a un espacio de nombres, no una copia de sus datos.
Validar e importar un catálogo pequeño
En este paso, comprobará un conjunto de datos antes de que un comando escriba todas sus entradas. Una operación masiva evita trabajo repetitivo, pero también repite cualquier error en todos los datos proporcionados. Empiece leyendo el archivo preparado:
cat redirects.json
Cada objeto tiene una key, como route:/old-start, y un value, como /docs/start. El prefijo route: agrupa los registros del catálogo; forma parte de la clave, no es un directorio. El destino es una ruta de este mismo sitio, no una URL externa arbitraria.
Escriba un script de validación normal de Node.js. El script lee un nombre de archivo, comprueba el arreglo y sus campos, rechaza las claves duplicadas e imprime un recuento únicamente después de que todas las entradas hayan pasado la validación. El Set recuerda las claves que ya se han visto. Las expresiones regulares limitan este conjunto de datos didáctico a rutas antiguas sencillas y destinos de documentación; son reglas de esta aplicación, no restricciones impuestas por 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
Debe aparecer Validated 5 unique redirect entries. Si la validación falla, corrija el archivo antes de importarlo. Rechazar las claves duplicadas es importante porque volver a escribir la misma clave reemplaza su valor.
Primero cree localmente un registro auxiliar que no sea una ruta y, después, importe el catálogo. El registro auxiliar le ayudará a comprobar que el mantenimiento posterior del catálogo conserva los demás datos.
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
Debe ver cinco entradas route: además de system:owner. bulk put escribe las entradas del archivo; no reemplaza todo el espacio de nombres ni elimina las claves que no aparecen en el archivo. Tampoco garantiza un cambio atómico visible en todas partes al mismo tiempo.
Ahora importe el mismo conjunto de datos revisado en el espacio de nombres en la nube de este laboratorio:
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
Confirme que hay seis claves. Las opciones de destino explícitas mantienen separadas la práctica local y las escrituras en la nube. Ejecute la comprobación de este paso antes de cambiar cualquier entrada.
Leer todas las páginas y servir redirecciones
En este paso, creará un Worker que enumere todas las claves de rutas y sirva sus redirecciones. Una sola llamada de KV a list() puede devolver solo una parte de una colección. El cursor es un marcador de continuación proporcionado por KV; debe enviarlo de vuelta sin modificar para solicitar la parte siguiente.
Escriba este controlador. El valor deliberadamente pequeño de limit: 2 hace visible la paginación con solo cinco registros. En código de producción normalmente se utiliza un tamaño de página mayor; en este laboratorio el conjunto de datos está limitado a veinte entradas para que el bucle sea pequeño.
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
El bucle do...while solicita al menos una página y continúa hasta que list_complete sea true. Mantiene prefix: "route:" en todas las solicitudes, lo que evita que el registro auxiliar del propietario entre en el catálogo. names.push(...) añade al resultado los nombres de las claves de cada página.
Un arreglo keys vacío no significa necesariamente que el listado haya terminado: las entradas eliminadas o caducadas pueden dejar una página sin claves devueltas mientras aún quedan más páginas. Por eso el bucle utiliza list_complete en lugar de la longitud del arreglo. El límite de páginas y la comprobación de la ausencia de un cursor producen un error controlado si esta demostración pequeña no puede completar el listado. Consulte Listado y paginación de KV.
Para las demás rutas, el Worker lee la clave de ruta correspondiente. Las rutas inexistentes devuelven 404; un destino admitido produce una respuesta 302 con una cabecera Location. El entorno de ejecución vuelve a comprobar los destinos para impedir que un valor de KV editado incorrectamente redirija a los visitantes a otro sitio. Las respuestas de /docs/ son marcadores de posición sencillos que muestran la ruta de destino, no un sitio de documentación completo.
npx wrangler dev --local --ip 0.0.0.0 --port 8080 > local.log 2>&1 &
DEV_PID=$!
cat local.log
Espere a que aparezca el mensaje de que el servidor está listo y, después, inspeccione el catálogo completo:
curl -i http://127.0.0.1:8080/catalog
Debe obtener cinco claves de rutas ordenadas y al menos tres páginas. Pueden aparecer páginas vacías adicionales; lo importante es que aparezca el conjunto completo de claves, sin ninguna entrada system:owner.
curl -i http://127.0.0.1:8080/old-start
Debe obtener el estado HTTP 302 y Location: http://127.0.0.1:8080/docs/start. De forma predeterminada, curl muestra la respuesta de redirección sin seguirla. Mantenga sin cambios el conjunto de datos local para compararlo más adelante.
Actualizar rutas seleccionadas y conservar los demás datos
En este paso, cambiará el catálogo en la nube sin reemplazar su espacio de nombres. La nueva página de inicio es /docs/getting-started, mientras que dos páginas temporales ya no deben redirigir.
npx wrangler kv key put route:/old-start /docs/getting-started --binding ROUTES --remote
La escritura de una clave seleccionada deja intactas las demás rutas. Para eliminar varias entradas, Wrangler acepta un arreglo JSON con los nombres exactos de las claves. Lea esta pequeña lista de retiro antes de ejecutar la eliminación:
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 se le solicita confirmación, compruebe que el binding y la operación indicada corresponden al espacio de nombres desechable de este laboratorio. La lista contiene únicamente dos claves de rutas; no contiene system:owner.
npx wrangler kv key list --binding ROUTES --remote
npx wrangler kv key get system:owner --binding ROUTES --remote --text
Debe obtener tres rutas restantes y el valor sin cambios labex-redirect-demo. No vuelva a ejecutar ahora la importación masiva original: sus valores antiguos desharían la actualización y restaurarían las claves retiradas.
Implemente el Worker, confirme el binding ROUTES y copie su dirección pública real:
npx wrangler deploy
WORKER_URL="https://YOUR_WORKER.YOUR_SUBDOMAIN.workers.dev"
curl -i "$WORKER_URL/catalog"
Primero confirme que /catalog devuelve HTTP 200 y las claves JSON esperadas. Si aparece una página de error de Cloudflare, espere un poco y repita las solicitudes de solo lectura. Una ruta retirada solo es correcta si devuelve HTTP 404 con el cuerpo de la aplicación Not found; el código de estado por sí solo no basta.
El catálogo debe contener únicamente route:/old-pricing, route:/old-start y route:/old-support. Compruebe las rutas modificada y retiradas:
curl -i "$WORKER_URL/old-start"
curl -i "$WORKER_URL/old-contact"
curl -i "$WORKER_URL/old-event"
La ruta de inicio debe redirigir a /docs/getting-started; las dos rutas retiradas deben devolver 404. Si los nuevos datos de la nube todavía no son visibles, espere a que se complete la propagación de KV y vuelva a intentar las comprobaciones de solo lectura. Una conexión fallida no demuestra que la retirada se haya realizado correctamente.
curl -i http://127.0.0.1:8080/catalog
El desarrollo local todavía muestra las cinco rutas originales. Esta diferencia confirma que los comandos de mantenimiento se dirigieron al almacén en la nube. En el Dashboard, seleccione la misma cuenta, abra Storage & databases → Workers KV e inspeccione el espacio de nombres de este laboratorio. Compare sus tres entradas de rutas y el registro de propietario conservado con la salida de los comandos. Este punto de control es de solo lectura; el nombre y el ID del espacio de nombres generados son específicos de esta ejecución.
Seleccione KV Pairs para ver los registros siguientes. Use Refresh si abrió el espacio de nombres antes de terminar los comandos de mantenimiento.

Eliminar los recursos de nube desechables
En este paso, eliminará ambos recursos mientras Wrangler siga autorizado. Un espacio de nombres puede existir después de eliminar su Worker, por lo que eliminar únicamente la aplicación no limpia sus datos.
Detenga el proceso de desarrollo local iniciado en este terminal:
kill "$DEV_PID"
Inspeccione las referencias de recursos guardadas antes de eliminar nada:
cat wrangler.jsonc
Confirme el nombre del Worker labex-routes-... y el ID del espacio de nombres ROUTES. Elimine el Worker seleccionado por esta configuración:
npx wrangler delete
Si se le solicita confirmación, compruebe que el nombre mostrado corresponde a este laboratorio y confirme con y. Después, elimine únicamente el espacio de nombres al que hace referencia ROUTES:
npx wrangler kv namespace delete --binding ROUTES
Revise el espacio de nombres en cualquier mensaje de confirmación antes de aceptar. Mantenga intacto wrangler.jsonc para que la comprobación independiente pueda identificar los recursos que deberían estar ausentes.
npx wrangler kv namespace list
El espacio de nombres de este laboratorio debe haber desaparecido; los espacios de nombres no relacionados deben permanecer. Actualice las listas del Dashboard para confirmar que el Worker y el espacio de nombres del laboratorio ya no aparecen. Una solicitud fallida o una sesión de inicio de sesión caducada no demuestra que se hayan eliminado. Ejecute la comprobación de este paso antes de cerrar la sesión para que pueda inspeccionar un inventario autorizado.
Finalizar la autorización de la VM
En este paso, desconectará Wrangler después de que la comprobación de limpieza haya finalizado correctamente. Cerrar la sesión termina la autorización de Wrangler guardada en esta VM; no elimina recursos de la nube ni cierra la sesión habitual del Dashboard en el navegador.
npx wrangler logout
npx wrangler whoami --json
Confirme que el resultado estructurado informa "loggedIn": false. Este comando sin autenticación puede finalizar con un estado de salida distinto de cero, lo cual es normal en este punto. Si solo aparece un error de conexión y no un estado de autenticación explícito, vuelva a intentarlo cuando la conexión funcione.
Los archivos locales restantes y el estado local de KV pertenecen a esta VM desechable. Son independientes de los recursos de la nube que ya eliminó. Ahora puede finalizar el laboratorio.
Resumen
Validó un conjunto de datos pequeño de redirecciones antes de realizar una escritura masiva, mantuvo explícitos los destinos local y en la nube, y recorrió todas las páginas de un listado de KV con prefijo. Cambió una ruta y retiró dos claves exactas, mientras conservaba un registro de propietario no relacionado. Las respuestas del Worker implementado confirmaron el nuevo destino y la ausencia de las rutas retiradas, mientras que el catálogo local conservó sus datos originales.
Por último, eliminó el Worker y el espacio de nombres desechables, y cerró la sesión. A continuación, trabajará con lecturas de configuración que pueden devolver temporalmente una versión anterior.



