Um serviço conectado com WU
Publique um contrato, autorize um cliente e percorra solicitações RPC com versões, validação, cancelamento e limpeza.
Do cliente a uma resposta
Se esta é sua primeira integração RPC, comece por Uma soma entre aplicações. Essa receita inclui todos os arquivos para seu workspace. Este capítulo amplia o padrão com descoberta de contratos, cancelamento e o serviço executável do laboratório.
Em Serviços e RPC, duas aplicações WU colaboram com permissões diferentes. O provedor publica qual serviço oferece e atende um canal; o cliente consome esse contrato e solicita uma resposta. O percurso permite testar dados válidos, erros, incompatibilidade de versões, cancelamento e remoção do provedor.
Cliente WU
→ consume('docs:backend:service', '^1.0.0')
→ request('docs:backend:request', solicitud)
→ handler del proveedor WU
→ respuesta { status, headers, body, execution }
As solicitações passam pelo RPC do WU dentro do runtime. status, headers e body são membros do contrato de resposta; não significam que o portal abriu uma conexão HTTP ou uma porta de servidor.
Solicitar e conceder a autoridade necessária
Cada manifesto declara as capacidades que sua app solicita. O provedor precisa de rpc.provide:docs:backend:*; o cliente, de rpc.call:docs:backend:*. O shell concede esses escopos ao inicializar ambas as aplicações:
await wu.init({
sandbox: 'module',
apps: [
{
name: 'backend-service',
url: '/microfrontends/backend-service',
grants: ['rpc.provide:docs:backend:*'],
},
{
name: 'backend-client',
url: '/microfrontends/backend-client',
grants: ['rpc.call:docs:backend:*'],
},
],
});
As solicitações do manifesto e as concessões do shell devem corresponder. A permissão efetiva vem da interseção delas. O código da app usa context.wu, a fachada com escopo recebida em mount; não precisa capturar o singleton privilegiado do host. A referência de permissões detalha os escopos e sua revogação.
Publicar o canal e o contrato
Dentro da montagem do provedor, appWu é essa fachada com escopo e handleRequest implementa o serviço:
const release = appWu.handle(
'docs:backend:request',
handleRequest,
{ version: '1.0.0', allow: ['backend-client'] },
);
const contract = appWu.provide(
'docs:backend:service',
{ channel: 'docs:backend:request', method: 'POST' },
{
version: '1.0.0',
shape: { channel: 'string', method: 'string' },
},
);
handle registra quem responde ao canal. provide publica os dados de que o consumidor precisa para descobri-lo. A lista de permissões do handler limita os solicitantes a backend-client; ter uma concessão não elimina essa verificação adicional. shape verifica membros do contrato e seus tipos, enquanto a validação do corpo pertence ao serviço.
No WU Framework 4.0.0, wu.handle(channel, handler, options) e wu.eventBus.handle(channel, handler, options) preservam versão e allowlist. Dentro de um microapp use context.wu.handle: além dessas opções, aplica a identidade e os grants do app. Consulte a página de versões para identificar o runtime do laboratório.
O nome publicado com provide pertence ao primeiro provedor. Outro app, ou o host ao tentar substituí-lo, recebe WU_CAPABILITY_OWNED até o proprietário executar revoke ou ser desmontado com unmount. A versão do contrato não permite ignorar essa propriedade.
Consumir e chamar pelo cliente
O cliente obtém um proxy do contrato e solicita um intervalo compatível. Acessar api.channel resolve o provedor disponível e verifica esse intervalo:
const api = appWu.consume('docs:backend:service', '^1.0.0');
const channel = api.channel;
const controller = new AbortController();
const pending = appWu.request(channel, {
method: api.method,
path: '/validate',
body: JSON.stringify({ name: 'catalog', entry: 'entry.js' }),
}, {
version: '^1.0.0',
timeout: 3500,
signal: controller.signal,
});
const response = await pending;
console.log(response.status, response.body);
Há duas verificações de compatibilidade: a do contrato consumido e a do handler RPC. O cenário de versão incompatível solicita ^2.0.0 ao contrato 1.0.0; falha ao resolvê-lo, antes de iniciar trabalho no serviço. Um provedor removido também não pode atender uma nova solicitação. Consulte eventos, RPC e contratos para suas assinaturas e erros.
Diferenciar uma resposta de uma rejeição
O serviço espera POST, uma rota conhecida e um corpo string de até 4096 bytes UTF-8.
| Solicitação | Resposta do serviço |
|---|---|
/validate com JSON válido e name/entry presentes |
200 com ok: true |
/validate com um manifesto que não atende a essas regras |
422 com erros de validação |
/uppercase |
200 com o texto ASCII convertido em maiúsculas |
/failure |
500 para a falha controlada do serviço |
/slow sem cancelar |
504 quando o limite de trabalho de 2500 ms expira |
| Rota desconhecida | 404 sem iniciar o trabalho |
| Método diferente de POST | 405 |
| Estrutura de solicitação inválida | 400 |
| Corpo que excede o limite | 413 |
Essas respostas resolvem a promise RPC com um objeto: o cliente deve verificar response.status. A incompatibilidade de contrato, a ausência do provedor ou o cancelamento são tratados como rejeições, com try/catch.
A receita de manifesto valida apenas name e entry. Seu resultado declara scope: "name+entry" e completeValidation: false; não verifica o manifesto inteiro, permissões, rotas publicadas ou a existência da entrada. Consulte configuração e manifestos e WU doctor para continuar o diagnóstico de um projeto.
Cancelar e desmontar sem manter trabalho ativo
Enquanto a solicitação estiver pendente, o cliente pode executar:
controller.abort();
O handler recebe o contexto RPC, que inclui signal. Neste exemplo, o provedor conecta esse sinal à interrupção do seu executor. Um handler que ignora signal pode continuar trabalhando mesmo depois de o cliente parar de esperar.
O prazo RPC de 3500 ms e o limite de trabalho de 2500 ms têm efeitos diferentes: o primeiro limita a espera do WU; o segundo permite ao serviço encerrar o trabalho e responder 504. A interface inclui uma receita lenta para observar o cancelamento antes dos dois prazos.
Ao desmontar o provedor, a implementação interrompe suas solicitações ativas e remove o que publicou:
backend.dispose();
release();
contract.revoke();
O WU também revoga a autoridade associada à app. Ao montar novamente, um novo handler e um novo contrato são registrados. Cada solicitação libera seu listener de abort, temporizador e executor ao terminar, falhar ou ser cancelada. O guia de ciclo de vida explica como vincular essa responsabilidade pelos recursos a mount e unmount.
Ler e verificar o exemplo
O código do provedor mostra o tratamento das solicitações e sua limpeza. Para executar as verificações pelo repositório do portal:
npm ci
npm run build
npm run dev:shell
# En otra terminal:
npm run test:backend
O teste percorre respostas, versão incompatível, revogação, remontagem, timeout, cancelamento e desmontagem durante uma solicitação. Também verifica se a execução não mantém Workers ao terminar e se o percurso não produz erros de página.
Implementação do exemplo
O provedor usa um programa WASI compilado e incluído no projeto, executado em um Worker. Isso permite processar dados reais e interromper o trabalho pelo navegador. O host e os arquivos virtuais pertencem à implementação do serviço; o contrato público estudado aqui é WU. O framework não incorpora um motor WASI geral.
Você pode substituir essa implementação por um serviço autorizado da sua aplicação, mantendo um contrato compatível e testando suas respostas, erros e limpeza. Um serviço remoto deve validar novamente identidade, permissões e dados. Para renderizar páginas no Node ou conectar um cliente MCP externo, seus processos e transportes continuam necessários: consulte SSR e IA/MCP.