Introdução
Um site pode lembrar escolhas de exibição, como um tema escuro ou o idioma preferido. Essas configurações costumam ser lidas em todas as visitas, mas alteradas apenas ocasionalmente, o que faz delas um bom exemplo para o Workers KV. Em vez de armazenar uma única palavra como sinalizador de recurso, você armazenará JSON: um texto que agrupa campos nomeados em um único valor. Seu Worker transformará esse texto novamente em configurações utilizáveis.
Neste laboratório, Alice e Bob são rótulos fictícios de contas, não usuários reais. Você atribuirá preferências diferentes a cada um e fará com que entradas ausentes ou corrompidas retornem um padrão sensato. Você também anexará metadados, uma pequena descrição armazenada junto com um valor, para identificar a revisão de uma configuração. Os números de revisão ajudam a explicar quais dados foram lidos; eles não garantem que todos os locais vejam imediatamente o valor mais recente.
Conclua primeiro o laboratório Create a Feature Flag Store. Este laboratório começa em uma VM nova, no diretório /home/labex/project/account-preferences, com Node.js 22.22.0 e o Wrangler 4.131.1 instalado localmente no projeto. Você criará um novo Worker e um namespace na sua conta de aprendizagem, usando as mesmas permissões de leitura da conta, gravação de Workers e gravação do KV. A demonstração pública expõe apenas configurações sintéticas de exibição; o rótulo da conta na URL não é autenticação. Não é necessário fazer upgrade pago nem comprar um domínio para este pequeno exercício. Faça a limpeza dos recursos antes de sair da VM.
Conectar um namespace de preferências
Neste passo, você conectará um namespace independente para as preferências de contas de exemplo. Um namespace agrupa os valores deste serviço; o binding PREFERENCES fornece ao Worker um nome estável para acessá-lo. Esta VM nova reutiliza o conhecimento da sua conta, mas não o namespace nem a autorização do laboratório anterior.
Entre no projeto preparado:
cd /home/labex/project/account-preferences
Gere um nome exclusivo uma única vez. openssl rand -hex 6 imprime um sufixo aleatório; $(...) insere esse sufixo no nome. A variável do shell mantém esse nome disponível para os comandos seguintes neste terminal.
WORKER_NAME="labex-prefs-$(openssl rand -hex 6)"
printf '%s\n' "$WORKER_NAME"
Autorize esta VM. Além de ler a identidade da sua conta, Workers Scripts Write permite fazer deploy e excluir recursos, e Workers KV Write permite gerenciar o namespace e as chaves deste laboratório.
npx wrangler login --device --browser=false --scopes account:read user:read workers_scripts:write workers_kv:write
Abra no navegador o link de dispositivo exibido, informe o código atual, revise as permissões e a conta de aprendizagem solicitadas e autorize o Wrangler. O acesso em segundo plano também pode aparecer na página de consentimento. Volte ao terminal e aguarde a conclusão do login.
Expanda Developer Platform para revisar Workers Scripts Write e Workers KV Storage Write. Essas são as mesmas permissões de gerenciamento de recursos apresentadas em Create a Feature Flag Store.
npx wrangler whoami --json
Confirme loggedIn: true e o name da conta de aprendizagem, mesmo que apenas uma conta esteja listada. Copie o id dessa conta. Salve-o na configuração abaixo, substituindo YOUR_ACCOUNT_ID antes de executar o comando. O here-document cat escreve em um arquivo tudo o que estiver entre as duas linhas JSON; > substitui o arquivo. O delimitador sem aspas permite que o shell insira $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
Crie um namespace nessa conta. O título dele compartilha o nome exclusivo do Worker, para que você possa reconhecer o par mais tarde. --update-config=false deixa a edição do binding visível para você, em vez de alterar o arquivo automaticamente.
npx wrangler kv namespace create "$WORKER_NAME-preferences" --update-config=false
A saída inclui o ID do novo namespace. Copie-o e substitua YOUR_ACCOUNT_ID e YOUR_NAMESPACE_ID nesta configuração completa. O nome do binding PREFERENCES é escolhido para o seu código; o ID identifica o recurso real da 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": "PREFERENCES", "id": "YOUR_NAMESPACE_ID" }
]
}
JSON
npx wrangler kv namespace list
Encontre o título do namespace deste laboratório e compare o ID dele com o ID no arquivo. Pode haver outros namespaces; não altere esses recursos. Essa configuração registra qual conta e qual recurso os comandos posteriores devem usar. Um binding é uma referência a um namespace, não uma cópia dos dados armazenados nele.
Armazenar valores JSON e metadados de revisão
Neste passo, você preparará um pequeno conjunto de dados com configurações normais e dois erros de dados realistas. O JSON usa aspas duplas para nomes de campos e strings. As aspas simples ao redor do argumento do comando impedem que o shell interprete essas aspas duplas do JSON.
Escreva as entradas locais. Alice prefere o modo escuro e inglês; Bob prefere o modo claro e francês. --metadata anexa um objeto JSON separado à chave. Aqui, o número de revision identifica a versão salva; não é uma decisão de segurança nem um contador automático de atualizações.
npx wrangler kv key put account:alice '{"theme":"dark","language":"en"}' --binding PREFERENCES --local --metadata '{"revision":7}'
npx wrangler kv key put account:bob '{"theme":"light","language":"fr"}' --binding PREFERENCES --local --metadata '{"revision":8}'
npx wrangler kv key put account:broken 'not-json' --binding PREFERENCES --local
npx wrangler kv key put account:invalid '{"theme":"neon","language":"en"}' --binding PREFERENCES --local
account:broken contém um texto que não pode ser analisado como JSON. account:invalid contém JSON válido, mas informa um tema que o aplicativo não oferece. Manter os dois casos ajuda você a distinguir análise sintática — ler a estrutura do texto — de validação — verificar se os campos fazem sentido para o aplicativo. Não crie uma entrada para Charlie; ela será usada para testar o caminho de chave ausente.
npx wrangler kv key list --binding PREFERENCES --local
Encontre quatro nomes de chave. Alice e Bob devem ter metadados de revisão 7 e 8. As outras duas entradas não têm metadados. A listagem mostra nomes e metadados; ela não mostra todos os valores.
npx wrangler kv key get account:alice --binding PREFERENCES --local --text
Espere {"theme":"dark","language":"en"}. O comando lê apenas o valor, portanto a revisão não faz parte deste texto JSON.
Agora escreva os mesmos quatro dados sintéticos no namespace em nuvem deste laboratório. Estes comandos remotos explícitos são operações separadas: gravações locais nunca são um upload para a Cloudflare.
npx wrangler kv key put account:alice '{"theme":"dark","language":"en"}' --binding PREFERENCES --remote --metadata '{"revision":7}'
npx wrangler kv key put account:bob '{"theme":"light","language":"fr"}' --binding PREFERENCES --remote --metadata '{"revision":8}'
npx wrangler kv key put account:broken 'not-json' --binding PREFERENCES --remote
npx wrangler kv key put account:invalid '{"theme":"neon","language":"en"}' --binding PREFERENCES --remote
npx wrangler kv key list --binding PREFERENCES --remote
Confirme os mesmos quatro nomes de chave e os respectivos metadados de revisão. Estes são registros descartáveis para demonstração. Não altere namespaces não relacionados.
Ler preferências com padrões seguros
Neste passo, você escreverá um handler que recupera o valor e os metadados juntos. getWithMetadata() retorna um objeto com os campos value e metadata. Uma chave ausente tem valor null. Os metadados também podem ser null, mesmo quando existe um valor.
Escreva este handler. O here-document JS entre aspas preserva o código exatamente. A rota aceita um rótulo curto de conta em letras minúsculas e cria uma chave distinta, como account:alice; ela nunca armazena a conta de uma solicitação anterior em uma variável global.
cat > src/index.js <<'JS'
function fallback(account, source) {
return Response.json({
account, theme: "light", language: "en", source, revision: null
});
}
export default {
async fetch(request, env) {
const match = new URL(request.url).pathname.match(/^\/preferences\/([a-z]{1,20})$/);
if (!match) return new Response("Not found", { status: 404 });
const account = match[1];
let entry;
try {
entry = await env.PREFERENCES.getWithMetadata(`account:${account}`, "text");
} catch {
return Response.json({ error: "Preferences temporarily unavailable" }, { status: 503 });
}
if (entry.value === null) return fallback(account, "missing");
let preferences;
try {
preferences = JSON.parse(entry.value);
} catch {
return fallback(account, "invalid");
}
if (!preferences || typeof preferences !== "object" || Array.isArray(preferences) ||
!["light", "dark"].includes(preferences.theme) ||
!["en", "fr"].includes(preferences.language)) {
return fallback(account, "invalid");
}
const revision = Number.isInteger(entry.metadata?.revision) && entry.metadata.revision > 0
? entry.metadata.revision : null;
return Response.json({
account, theme: preferences.theme, language: preferences.language,
source: "stored", revision
});
}
};
JS
O primeiro try/catch trata uma leitura indisponível do KV com HTTP 503, que significa que o serviço está temporariamente indisponível. Ele não finge que a conta está ausente. A leitura como "text" seguida da análise em um try/catch separado permite identificar JSON corrompido sem confundi-lo com uma falha de armazenamento. A leitura usando a opção "json" pode fazer a análise automaticamente, mas esta lição separa as duas operações para deixar visíveis os caminhos de falha.
Tanto as preferências ausentes quanto as inválidas usam como fallback o modo claro e o inglês. O campo source explica por que o fallback foi usado. Para um valor válido, a resposta usa apenas os campos de tema e idioma aceitos. entry.metadata?.revision trata com segurança a ausência de metadados; uma revisão que seja um inteiro positivo é exibida, caso contrário o valor será null. Esses padrões mantêm utilizáveis as opções de exibição, que são opcionais; eles não substituem autenticação nem permissões.
Inicie o Worker local, salve o ID do processo e aguarde a mensagem de pronto:
npx wrangler dev --local --ip 0.0.0.0 --port 8080 > local.log 2>&1 &
DEV_PID=$!
cat local.log
O processo em segundo plano mantém o terminal livre; local.log contém a saída dele. Repita o comando de log se a inicialização ainda não tiver terminado. Solicite cada caso:
curl -i http://127.0.0.1:8080/preferences/alice
curl -i http://127.0.0.1:8080/preferences/bob
curl -i http://127.0.0.1:8080/preferences/charlie
curl -i http://127.0.0.1:8080/preferences/broken
curl -i http://127.0.0.1:8080/preferences/invalid
Os cinco casos devem retornar HTTP 200 com JSON. Confira as diferenças:
| Conta | Tema | Idioma | Origem | Revisão |
|---|---|---|---|---|
| alice | dark | en | stored | 7 |
| bob | light | fr | stored | 8 |
| charlie | light | en | missing | null |
| broken | light | en | invalid | null |
| invalid | light | en | invalid | null |
Por exemplo, o corpo da resposta de Alice é {"account":"alice","theme":"dark","language":"en","source":"stored","revision":7}. Solicite Alice novamente depois de Bob: as configurações ainda devem pertencer a Alice. Mantenha o servidor local em execução até a limpeza.
Verificar o serviço de preferências implantado
Neste passo, você executará os mesmos casos usando o namespace em nuvem. A verificação independente na nuvem confirma a conta selecionada, o binding do namespace implantado, os registros armazenados e as respostas HTTP reais.
npx wrangler deploy
Confirme no resultado o nome gerado do Worker e o binding PREFERENCES. Copie o endereço público implantado para a variável abaixo, substituindo o exemplo:
WORKER_URL="https://YOUR_WORKER.YOUR_SUBDOMAIN.workers.dev"
curl -i "$WORKER_URL/preferences/alice"
curl -i "$WORKER_URL/preferences/bob"
curl -i "$WORKER_URL/preferences/charlie"
curl -i "$WORKER_URL/preferences/broken"
curl -i "$WORKER_URL/preferences/invalid"
Compare as cinco respostas com a tabela local. Alice e Bob devem manter suas próprias preferências e seus metadados de revisão; Charlie e os dois registros corrompidos devem usar os padrões explicados. Se uma entrada gravada recentemente ainda não estiver visível, aguarde a propagação do KV e tente novamente. Um hostname público também pode precisar de algum tempo após o primeiro deploy. Não considere um erro de conexão como uma resposta de fallback.
No Dashboard, selecione a conta de aprendizagem, abra Storage & databases → Workers KV e encontre o namespace labex-prefs-...-preferences deste laboratório. Selecione KV Pairs, inspecione os quatro registros e clique em View ao lado de account:alice para comparar o valor JSON com a saída do terminal. Essa visualização mostra chaves e valores; compare os metadados de revisão usando a lista de chaves do Wrangler anterior e a resposta da API. O nome exclusivo do namespace e os IDs serão diferentes do exemplo.

O endpoint público é apenas uma demonstração de configurações sintéticas de exibição. Um serviço real de preferências privadas identificaria quem fez a solicitação antes de decidir qual chave de conta essa pessoa pode acessar.
Excluir os recursos descartáveis da nuvem
Neste passo, você removerá os dois recursos enquanto o Wrangler ainda estiver autorizado. Um namespace pode existir mesmo depois que seu Worker for excluído; portanto, excluir apenas o aplicativo não remove os dados.
Pare o processo de desenvolvimento local iniciado neste terminal:
kill "$DEV_PID"
Inspecione as referências de recursos salvas antes de excluir qualquer coisa:
cat wrangler.jsonc
Confirme o nome do Worker labex-prefs-... e o ID do namespace PREFERENCES. Exclua o Worker selecionado por esta configuração:
npx wrangler delete
Se uma confirmação for solicitada, verifique se o nome exibido corresponde a este laboratório e confirme com y. Em seguida, exclua apenas o namespace referenciado por PREFERENCES:
npx wrangler kv namespace delete --binding PREFERENCES
Revise o namespace em qualquer confirmação antes de aceitá-la. Mantenha wrangler.jsonc intacto para que a verificação independente possa identificar os recursos que devem estar ausentes.
npx wrangler kv namespace list
O namespace deste laboratório não deve aparecer; namespaces não relacionados devem permanecer. Atualize as listas do Dashboard para confirmar que o Worker e o namespace do laboratório desapareceram. Uma solicitação com falha ou um login expirado não comprova a exclusão. Execute a verificação deste passo antes de sair da conta, para que ela possa consultar um inventário autorizado.
Encerrar a autorização da VM
Neste passo, você desconectará o Wrangler depois que a verificação da limpeza for aprovada. Sair da conta encerra a autorização do Wrangler salva nesta VM; isso não exclui recursos da nuvem nem encerra a sessão do Dashboard no navegador comum.
npx wrangler logout
npx wrangler whoami --json
Confirme que o resultado estruturado informa "loggedIn": false. Este comando não autenticado pode terminar com um status de saída diferente de zero, o que é esperado neste caso. Se houver apenas um erro de conexão, sem um estado explícito de autenticação, tente novamente quando a conexão estiver funcionando.
Os arquivos locais restantes e o estado local do KV pertencem a esta VM descartável. Eles são separados dos recursos da nuvem que você já excluiu. Agora você pode concluir o laboratório.
Resumo
Você armazenou preferências estruturadas e metadados de revisão no Workers KV e depois os leu por meio de um binding do Worker. Manteve as configurações de Alice e Bob separadas e fez com que valores ausentes, malformados e não suportados produzissem padrões explicados. Você também distinguiu uma falha de armazenamento de um registro ausente, em vez de ocultar ambos atrás da mesma resposta.
Depois de comparar as respostas locais e da nuvem, você removeu o Worker e o namespace descartáveis e encerrou a sessão. Em seguida, você atribuirá aos avisos temporários um prazo no aplicativo e uma expiração no KV.



