Introdução
Uma API de suporte precisa de um catálogo pertencente a outro Worker. Você conectará a API pública a um catálogo interno fornecido, reproduzirá e corrigirá um binding ausente e fará o deploy dos dois serviços, mantendo o catálogo sem um endpoint público.
Use sua própria conta de aprendizado do Cloudflare e os conhecimentos de autorização, configuração e deployment dos laboratórios anteriores. Esta VM independente começa em /home/labex/project/service-binding com Node.js 22.22.0, Wrangler 4.131.1 instalado localmente no projeto e um fixture de catálogo sintético. Nenhuma VM ou recurso anterior é reutilizado. O exercício não exige domínio comprado, banco de dados nem upgrade pago; as pequenas requisições contam para o uso normal da conta.
Mantenha um terminal aberto. Você usará dois processos locais, criará dois Workers descartáveis na nuvem com nomes exclusivos, verificará a conexão entre eles, excluirá o chamador e a dependência e, por fim, fará logout antes de encerrar a VM.
Reproduzir um service binding ausente
Nesta etapa, você criará uma API pública cuja dependência do catálogo está deliberadamente sem configuração. Um Worker fornecido separado é responsável por duas entradas sintéticas do catálogo. Por enquanto, os dois processos serão executados apenas nesta VM.
cd /home/labex/project/service-binding
node --version
npx wrangler --version
cat catalog/index.js
Espere ver Node v22.22.0 e Wrangler 4.131.1. A configuração instalou as dependências locais do projeto; em outra máquina, use npm ci com o lockfile deste projeto. O fixture retorna um rótulo público do serviço, duas entradas e um valor de consulta sintético opcional probe para rastrear uma requisição. Ele não armazena dados.
Gere um nome-base descartável e registre as identidades dos dois recursos na configuração comum. Mantenha este terminal aberto para que WORKER_NAME continue disponível. O campo main do catálogo é relativo ao próprio diretório de configuração.
WORKER_NAME="labex-binding-$(openssl rand -hex 6)"
cat > wrangler.jsonc <<CONFIG
{
"name": "$WORKER_NAME",
"main": "src/index.js",
"compatibility_date": "2026-09-14",
"workers_dev": true,
"preview_urls": false,
"services": []
}
CONFIG
cat > catalog/wrangler.jsonc <<CONFIG
{
"name": "$WORKER_NAME-catalog",
"main": "index.js",
"compatibility_date": "2026-09-14",
"workers_dev": false,
"preview_urls": false,
"routes": [],
"vars": {"SERVICE_ID": "$WORKER_NAME-catalog"}
}
CONFIG
O catálogo desativa tanto workers.dev quanto as URLs de preview e não possui rotas. O desenvolvimento local ainda expõe uma porta de loopback para testes; isso não cria um endpoint público na nuvem. A lista services vazia da API pública é o defeito que você diagnosticará.
Escreva o handler público. /health continua independente. /catalog verifica se o binding existe antes de fazer uma chamada interna. catalog.internal é uma URL de placeholder totalmente qualificada, não um nome DNS a ser registrado: env.CATALOG seleciona o destino. Construímos uma nova requisição GET somente com o valor de consulta pretendido, em vez de encaminhar cabeçalhos arbitrários do cliente.
cat > src/index.js <<'JS'
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === '/health' && request.method === 'GET') {
return Response.json({status: 'ok'});
}
if (url.pathname !== '/catalog') return Response.json({error: 'not_found'}, {status: 404});
if (request.method !== 'GET') {
return Response.json({error: 'method_not_allowed'}, {status: 405, headers: {Allow: 'GET'}});
}
if (!env.CATALOG) return Response.json({error: 'catalog_binding_missing'}, {status: 503});
// This hostname completes the Request URL. The binding selects the target Worker.
const target = new URL('https://catalog.internal/catalog');
target.searchParams.set('probe', url.searchParams.get('probe') || '');
try {
return await env.CATALOG.fetch(new Request(target, {method: 'GET'}));
} catch {
return Response.json({error: 'catalog_unavailable'}, {status: 502});
}
}
};
JS
Inicie o catálogo fornecido e a API como tarefas em segundo plano separadas, usando portas HTTP e de inspector distintas. Os logs tornam a inicialização visível; & devolve o prompt do shell.
npx wrangler dev --config catalog/wrangler.jsonc --ip 127.0.0.1 --port 8081 --inspector-port 9230 > catalog.log 2>&1 &
npx wrangler dev --config wrangler.jsonc --ip 127.0.0.1 --port 8080 --inspector-port 9231 > api.log 2>&1 &
cat catalog.log
cat api.log
Aguarde a indicação de prontidão nos dois logs, repetindo cat se necessário, e depois inspecione as respostas:
curl -i http://127.0.0.1:8081/catalog
curl -i http://127.0.0.1:8080/health
curl -i http://127.0.0.1:8080/catalog
O catálogo retorna 200 e suas duas entradas; health retorna 200 {"status":"ok"}; a rota de catálogo da API retorna 503 {"error":"catalog_binding_missing"}. A dependência está em execução, mas o chamador não tem uma capacidade configurada para alcançá-la. Faça a verificação enquanto esse estado de binding ausente estiver presente.
Declarar e testar a conexão interna
Nesta etapa, você corrigirá a configuração sem alterar o código da API. Inspecione as tarefas em segundo plano reais e pare somente o processo da API; o exemplo pressupõe que ele seja a tarefa 2.
jobs
kill %2
cat > wrangler.jsonc <<CONFIG
{
"name": "$WORKER_NAME",
"main": "src/index.js",
"compatibility_date": "2026-09-14",
"workers_dev": true,
"preview_urls": false,
"services": [{"binding": "CATALOG", "service": "$WORKER_NAME-catalog"}]
}
CONFIG
binding é o nome da propriedade disponível como env.CATALOG. service é o nome exato configurado para o Worker de destino. Um erro de grafia em qualquer uma das partes é um problema diferente: uma propriedade ausente aciona o 503 explícito, enquanto um destino indisponível pode acionar 502 ou um erro de inicialização/deployment. Não substitua a chamada do binding por uma URL pública de fetch.
npx wrangler dev --config wrangler.jsonc --ip 127.0.0.1 --port 8080 --inspector-port 9231 > api.log 2>&1 &
cat api.log
Aguarde a indicação de prontidão e inspecione a tabela de bindings. O Wrangler encontra o catálogo em execução pelo nome e informa o status da conexão. Se estiver desconectado, confirme o processo do catálogo e os dois nomes configurados e tente novamente.
curl -i "http://127.0.0.1:8080/catalog?probe=local-check"
curl -i -X POST http://127.0.0.1:8080/catalog
curl -i http://127.0.0.1:8080/missing
A primeira resposta é 200, com o rótulo exato do serviço do catálogo, os dois itens e probe: local-check. A verificação do método retorna 405, e a rota desconhecida retorna 404. Faça a verificação com os dois servidores em execução; ela envia um novo probe pela API pública e verifica o contrato completo.
Os bindings pertencem aos ambientes de configuração. Se você usar --env preview posteriormente, declare o array services completo em env.preview e aponte-o para o destino implantado pretendido; os service bindings não são herdados do nível superior. Este laboratório usa um ambiente sem nome e nunca passa --env. Consulte Ambientes do Wrangler e a interface HTTP de service binding.
Fazer o deploy do serviço interno e da API pública
Nesta etapa, você fará o deploy da mesma conexão na sua própria conta de aprendizado. Pare as duas tarefas locais mostradas por jobs; o exemplo pressupõe que sejam as tarefas 1 e 2.
jobs
kill %1 %2
npx wrangler login --device --browser=false --scopes account:read user:read workers_scripts:write workers_tail:read
Abra o link de dispositivo exibido no navegador em que você já fez login, insira o código atual, revise as permissões do Wrangler e o acesso em segundo plano e selecione somente sua conta de aprendizado, como ensinado anteriormente. Aguarde o terminal terminar.
npx wrangler whoami --json
Confirme loggedIn: true e o nome e o ID reais da conta, mesmo que apenas uma conta seja listada. Substitua YOUR_ACCOUNT_ID nos dois comandos abaixo pelo mesmo ID; mantenha os nomes gerados originalmente e o binding.
cat > catalog/wrangler.jsonc <<CONFIG
{
"name": "$WORKER_NAME-catalog",
"main": "index.js",
"compatibility_date": "2026-09-14",
"account_id": "YOUR_ACCOUNT_ID",
"workers_dev": false,
"preview_urls": false,
"routes": [],
"vars": {"SERVICE_ID": "$WORKER_NAME-catalog"}
}
CONFIG
cat > wrangler.jsonc <<CONFIG
{
"name": "$WORKER_NAME",
"main": "src/index.js",
"compatibility_date": "2026-09-14",
"account_id": "YOUR_ACCOUNT_ID",
"workers_dev": true,
"preview_urls": false,
"services": [{"binding": "CATALOG", "service": "$WORKER_NAME-catalog"}]
}
CONFIG
Faça primeiro o deploy do destino para que a dependência declarada pelo Worker público já exista. Estes são dois deployments independentes, não uma release atômica.
npx wrangler deploy --config catalog/wrangler.jsonc
npx wrangler deploy --config wrangler.jsonc
O catálogo não deve ter uma rota pública. A API exibirá sua URL workers.dev e seu binding CATALOG. Copie essa URL exata da API para a variável abaixo; reutilize o subdomínio workers.dev já existente na conta. Uma conta que usa workers.dev pela primeira vez pode seguir o prompt de subdomínio disponível do Wrangler sem alterar um subdomínio existente.
API_URL="https://YOUR_WORKER.YOUR_SUBDOMAIN.workers.dev"
curl -i "$API_URL/health"
curl -i "$API_URL/catalog?probe=remote-check"
Espere um health 200 e o resultado do catálogo com probe: remote-check. A propagação inicial do deployment/nome do host pode exigir uma nova tentativa após alguns instantes; um 503 ou 502 persistente exige a inspeção da configuração do binding e do deployment do destino.
Abra a mesma conta de aprendizado no Dashboard, acesse Compute → Workers & Pages e localize os dois nomes exatos. Abra a aba Bindings da API pública. O diagrama identifica o binding CATALOG; na tabela abaixo, compare Name (CATALOG) e Value (o Worker -catalog correspondente). O nome do binding torna-se env.CATALOG no handler, enquanto o valor identifica a dependência implantada.

Siga o link do Worker de catálogo nessa tabela e selecione a aba Domains. Confirme que o breadcrumb superior agora termina em -catalog. Em Worker URL, os switches Production e Preview devem estar desativados. Em Custom Domains and Routes, não deve haver entradas, como mostrado abaixo.

Estes são nomes de exemplo; use o sufixo gerado e o subdomínio da sua conta. Um switch desativado significa que o endereço exibido não é um entrypoint público habilitado. A requisição funcional da API acima alcança este Worker por meio do service binding. Mantenha esta verificação somente para leitura: não habilite um endpoint público, não adicione uma rota nem duplique o binding para fazer a chamada interna funcionar. Faça a verificação: ela confirma independentemente a propriedade da conta, o service binding implantado, as configurações dos endpoints e a resposta remota com um novo probe. Desativar esses endpoints não impede operadores autorizados da conta de associar-se ao serviço ou alterá-lo; isso não é um sistema de login de usuário.
Excluir o chamador antes da dependência
Nesta etapa, você removerá os dois Workers descartáveis da nuvem enquanto ainda estiver autorizado. Os arquivos de configuração são o inventário dos seus recursos. Confirme os nomes gerados e o ID da conta antes de excluir.
cat wrangler.jsonc
cat catalog/wrangler.jsonc
Exclua primeiro o chamador público e depois o catálogo interno. Isso evita deixar um chamador implantado apontando para um serviço removido. Em cada prompt, verifique o nome exato do laboratório e pressione a única tecla y.
npx wrangler delete --config wrangler.jsonc
npx wrangler delete --config catalog/wrangler.jsonc
O Wrangler 4.131.1 pode informar um erro de autenticação legado do Workers Sites KV depois de excluir o script. Não amplie as permissões nem considere esse diagnóstico uma prova da exclusão. Atualize Workers & Pages e faça a verificação: um inventário autorizado bem-sucedido deve mostrar que os dois nomes exatos estão ausentes. Falhas de rede/autenticação são inconclusivas. Preserve os outros Workers, a conta e o subdomínio existente.
Desconectar a VM do laboratório
Nesta etapa, você removerá a autorização da VM depois de verificar as duas exclusões na nuvem.
npx wrangler logout
npx wrangler whoami --json
Espere ver explicitamente "loggedIn": false. O comando de status sem autenticação pode terminar com código diferente de zero; o resultado estruturado é a evidência importante. Faça a verificação e encerre a VM. O login do navegador no Dashboard é separado e pode continuar ativo para outro laboratório. Encerrar a VM não substitui a exclusão na nuvem nem o logout.
Resumo
Você diagnosticou uma dependência em execução que estava ausente nos bindings do chamador, declarou o nome exato do serviço e enviou requisições por meio de env.CATALOG.fetch(). Os probes locais e implantados retornaram a identidade e os dados do catálogo. Você inspecionou a conexão implantada e manteve os endpoints públicos do serviço interno desativados; depois, excluiu o chamador antes da dependência e desconectou a VM.
Os service bindings tornam explícitas as conexões internas entre Workers. Ambientes nomeados exigem suas próprias declarações, e a conectividade local, por si só, não comprova a propriedade remota nem a configuração dos endpoints.

