WU / DOCSMICROFRONTENDS UNIVERSAIS
PT

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.

CONSTRUA O WU CONOSCO

Encontrou um bug? Tem uma ideia?

Sua experiência melhora o WU. Conte o que falhou ou ajude a manter seu desenvolvimento.