Pular para o conteúdo principal

Aula 2: Arquiteturas e Frameworks Multiplataforma

A aula anterior mostrou as forças que atuam sobre uma aplicação que precisa atender navegador e celular. Esta aula trata das escolhas que respondem a essas forças — e do preço de cada uma.

São duas decisões distintas, e confundi-las é a origem de boa parte da confusão inicial:

  1. Como o sistema se divide? Um programa que faz tudo, ou um serviço com clientes separados?
  2. Como o aplicativo móvel é construído? Nativo, híbrido, compilado ou web?

A primeira decisão é de arquitetura; a segunda, de estratégia de implementação. Ao final, a aula registra qual combinação esta disciplina adota e por quê — não porque seja a única defensável, mas porque as razões da escolha são o próprio conteúdo.

O que vem depoisOnde
A linguagem comum ao serviço e ao cliente webAula 3 — TypeScript
O contrato entre o serviço e os clientesAula 4 — API REST
A implementação do serviçoMódulo 2 — NestJS

Objetivos

Ao final desta aula, você deve ser capaz de:

  • Comparar a arquitetura acoplada (renderizada no servidor) com a arquitetura desacoplada baseada em API, identificando o que trafega na rede em cada uma.
  • Explicar o que efetivamente executa no dispositivo em cada uma das quatro estratégias de desenvolvimento mobile.
  • Justificar a escolha de uma estratégia para um cenário dado, considerando desempenho, acesso a recursos, custo de manutenção e prazo.
  • Descrever a arquitetura adotada na disciplina e o papel de cada tecnologia nela.
  • Reconhecer os limites das arquiteturas desacopladas — o custo que elas cobram em troca da flexibilidade.
  • Preparar o ambiente de desenvolvimento das três frentes e verificar a instalação.

Parte 1 — Acoplado ou desacoplado

Comecemos pela decisão que condiciona todas as outras.

Comparação entre o monolito renderizado no servidor, que devolve páginas HTML prontas, e o serviço desacoplado, que devolve dados consumidos por vários clientes

A diferença não é a linguagem nem o framework. É o que trafega na rede.

Renderizado no servidorDesacoplado (API)
O servidor devolveA página HTML montadaOs dados, em JSON
Quem monta a telaO servidorCada cliente
Ao navegarRecarrega a página inteiraAtualiza apenas o que mudou
Um segundo clienteExige um novo servidor de apresentaçãoConsome a mesma API
Interface e regraEvoluem juntas, no mesmo projetoEvoluem em ritmos separados
Primeira cargaRápida: o HTML já vem prontoMais lenta: baixa o aplicativo, depois os dados
Indexação por buscadoresNaturalExige cuidado adicional
Nenhum dos dois é obsoleto

Aplicações renderizadas no servidor continuam sendo a melhor escolha para sites de conteúdo, portais institucionais e sistemas internos com um cliente só. Programação Web Java trabalha exatamente esse modelo com Jakarta Faces — e faz sentido, porque lá o cliente é um só. A arquitetura desacoplada não é "melhor": ela paga um custo inicial que só se justifica quando há mais de um cliente, ou quando eles evoluem em ritmos diferentes.

O híbrido que virou padrão

Vale notar que a fronteira se dissolveu. Next.js — o framework do Módulo 3 — renderiza no servidor e consome API: a primeira tela vem montada, para ser rápida e indexável, e a navegação seguinte busca só os dados. Os dois modelos convivem no mesmo projeto, e escolher entre eles passou a ser uma decisão por tela, não por sistema.

O que não muda é a posição das regras de negócio: elas continuam no serviço. Um servidor Next.js renderizando HTML ainda é um cliente da API — não é o dono das regras.

O custo que a arquitetura desacoplada cobra

A separação não é gratuita, e vale ser explícito quanto a isso:

  • Mais partes móveis. Três projetos para versionar, testar e publicar em vez de um.
  • Latência somada. Uma tela que precisa de três recursos pode fazer três viagens à rede.
  • Contrato para manter. Mudar um campo deixa de ser uma refatoração e vira uma negociação entre times.
  • Autenticação distribuída. Sessão em servidor não serve mais; é preciso token, e tratá-lo em cada cliente.
  • Depuração mais difícil. O erro pode estar em qualquer um dos três lados, ou na fronteira entre eles.

Vale a pena quando há mais de um cliente — que é exatamente o nosso caso.


Parte 2 — As quatro estratégias de desenvolvimento mobile

Decidida a arquitetura, resta a segunda pergunta: como o aplicativo é construído? Quatro respostas dividem o mercado, e a diferença entre elas está em uma única coisa: o que desenha a interface na tela.

Pilhas de execução das quatro estratégias: nativo, híbrido com WebView, cross-platform compilado e web app, todas sobre o sistema operacional e o hardware

Nativo

Escrito na linguagem oficial de cada plataforma — Kotlin no Android, Swift no iOS — usando diretamente os componentes de interface do sistema.

  • A favor: desempenho máximo, acesso imediato a qualquer recurso e a APIs recém-lançadas, aparência exatamente igual à da plataforma.
  • Contra: duas bases de código, duas equipes ou uma equipe que domina duas linguagens, e todo recurso implementado duas vezes.
  • Quando escolher: quando desempenho gráfico, integração profunda com o sistema ou acesso a APIs muito recentes forem requisito, e houver equipe para sustentar dois projetos.

Híbrido (WebView)

A interface é HTML, CSS e JavaScript, exibida dentro de um componente de navegador embutido no aplicativo — a WebView. Uma ponte dá acesso a recursos nativos. Exemplos: Ionic, Apache Cordova, Capacitor.

  • A favor: aproveita conhecimento e código da web; uma base para as duas plataformas; ciclo de desenvolvimento curto.
  • Contra: o desempenho é o da WebView; animações e listas longas costumam denunciar a origem; a aparência é a mesma nos dois sistemas, o que nem sempre é desejável.
  • Quando escolher: aplicativos majoritariamente de conteúdo, com pouca interação complexa, ou quando já existe uma aplicação web madura para reaproveitar.

Cross-platform compilado

O código é escrito uma vez, em uma linguagem própria, e compilado para código nativo. A interface não usa os componentes do sistema: o framework traz o próprio motor gráfico e desenha tudo em um canvas. É a estratégia do Flutter (Dart) e, com um arranjo diferente, do React Native.

  • A favor: desempenho próximo do nativo; uma base de código; interface idêntica nas duas plataformas por construção; ciclo de desenvolvimento rápido, com hot reload.
  • Contra: depende do framework para alcançar recursos do sistema — o que geralmente significa aguardar um plugin; o binário é maior; APIs recém-lançadas chegam com atraso.
  • Quando escolher: aplicativos com interface rica e interativa, equipe única e necessidade de acesso a recursos do dispositivo. É a escolha desta disciplina.
Flutter e React Native resolvem o mesmo problema de formas diferentes

O React Native traduz os componentes do código para componentes nativos do sistema; o Flutter desenha os seus próprios. A consequência prática: no React Native, um botão é um botão do Android ou do iOS, e a aparência muda entre as plataformas; no Flutter, é o mesmo botão em ambas. Nenhuma das duas abordagens é superior — elas otimizam coisas diferentes. Usamos Flutter porque o controle total sobre a renderização torna o comportamento mais previsível, e porque Dart permite comparar diretamente com o TypeScript usado nas outras duas frentes.

Web app e PWA

Não há aplicativo: há um site, acessado pelo navegador do celular. Um Progressive Web App acrescenta manifesto, ícone e service worker, podendo ser instalado na tela inicial e funcionar parcialmente offline.

  • A favor: uma base de código para tudo; publicação imediata, sem loja; atualização instantânea para todos os usuários.
  • Contra: acesso restrito a recursos do dispositivo, com diferenças relevantes entre navegadores; sem presença na loja; notificações push com suporte desigual.
  • Quando escolher: quando não há necessidade real de recursos do dispositivo nem de estar na loja. É a opção de menor custo — e por isso a primeira a ser descartada com honestidade, não por reflexo.

Em uma tabela

NativoHíbridoCompiladoWeb app / PWA
LinguagemKotlin, SwiftHTML/CSS/JSDart, JSHTML/CSS/JS
Quem desenha a telaO sistemaA WebViewO motor do frameworkO navegador
DesempenhoMáximoLimitadoPróximo do nativoO do navegador
Recursos do dispositivoTotalVia ponteVia pluginsRestrito
Bases de códigoUma por plataformaUmaUmaUma
Está na lojaSimSimSimNão
AtualizaçãoPela lojaPela lojaPela lojaImediata

Parte 3 — Como escolher

Não existe estratégia correta em abstrato. Existe a que melhor equilibra requisitos, prazo e equipe — e a decisão costuma caber em três perguntas.

Árvore de decisão com três perguntas que levam a web app, nativo, híbrido ou cross-platform compilado

1. Precisa estar na loja ou usar recursos do dispositivo? Se não, um web app resolve com o menor custo possível. Descarte essa opção apenas com um requisito na mão, não por hábito.

2. Uma única base de código atende as duas plataformas? Se o produto depende de desempenho gráfico extremo, de integração profunda com o sistema ou de APIs lançadas há poucos meses, a resposta é não — e a estratégia é nativa, com o custo de dois projetos assumido conscientemente.

3. A tela é sobretudo conteúdo que já existe na web? Se sim, o híbrido aproveita o que já está pronto. Se não — se há interação, animação, listas longas, estado complexo — o cross-platform compilado entrega resultado próximo do nativo com uma base de código só.

Os critérios por trás das perguntas

CritérioPergunta que ele responde
Requisitos de recursoO app precisa de câmera, GPS, biometria, notificações, uso offline?
Exigência de interfaceHá animação, gesto complexo, lista muito longa, gráfico interativo?
EquipeQue linguagens a equipe domina hoje? Quantas pessoas mantêm o projeto?
Prazo e orçamentoDuas bases de código dobram o custo de cada funcionalidade
Vida útilUm piloto de três meses e um produto de cinco anos não pedem a mesma escolha
EcossistemaExiste plugin mantido para o que você precisa, ou será preciso escrever código nativo?
O erro mais caro é escolher por preferência

"Prefiro X" não é critério. A pergunta é sempre qual restrição do produto essa escolha atende, e qual custo ela impõe. Um argumento de escolha que não menciona custo está incompleto.


Parte 4 — A arquitetura desta disciplina

Com o vocabulário estabelecido, dá para enunciar a arquitetura do semestre e justificar cada peça.

Arquitetura da disciplina: clientes Next.js e Flutter consomem, via HTTP e JSON, um contrato REST implementado por um serviço NestJS apoiado em PostgreSQL
CamadaTecnologiaPor que
ServiçoNestJS (TypeScript) sobre Node.jsEstrutura opinativa, com módulos, injeção de dependência e validação — os mesmos conceitos de Jakarta EE, em outro ecossistema
PersistênciaPostgreSQL, acessado por ORMBase relacional madura, com migrações versionadas
ContratoREST sobre HTTP, descrito em OpenAPIIndependente de linguagem: os dois clientes leem o mesmo documento
Cliente webNext.js + React (TypeScript)Componentização, roteamento e escolha de estratégia de renderização por tela
Cliente mobileFlutter (Dart)Uma base de código, desempenho próximo do nativo, acesso a recursos via plugins

Três decisões merecem justificativa explícita, porque são as que voltam nas provas e nos projetos:

Por que o backend vem primeiro. Os dois clientes consomem os serviços construídos nele. Começar pelo cliente significaria inventar um contrato que ainda não existe — e depois refazê-lo.

Por que TypeScript no serviço e no cliente web. Uma linguagem a menos para aprender, e a possibilidade de compartilhar os tipos do contrato entre os dois lados. O cliente mobile usa Dart, e essa diferença é proposital: mostra que o contrato funciona sem compartilhar código.

Por que o contrato é o centro do diagrama. É a única peça que nenhum dos três lados pode mudar sozinho. Toda a aula 4 é dedicada a ele.

Se você cursou Programação Web Java

Vale mapear os conceitos, porque eles se transferem quase inteiros: injeção de dependência (CDI → NestJS providers), API REST (Jakarta REST → NestJS controllers), mapeamento objeto-relacional (JPA → ORM) e validação declarativa (Bean Validation → class-validator). O padrão é o mesmo; muda a sintaxe e o ecossistema. Comparar as duas stacks é uma das formas mais rápidas de consolidar o conteúdo.


Parte 5 — O ambiente de desenvolvimento

Os exemplos da disciplina são executáveis. Esta seção reúne o mínimo para que a próxima aula não comece com problema de instalação.

FerramentaVersão sugeridaPara quê
Node.js22 LTS ou superiorRuntime do serviço e do cliente web
npm ou pnpma que acompanha o NodeGerenciamento de pacotes
NestJS CLI11.xGeração e execução do serviço
Next.js15.x (App Router)Cliente web
Flutter SDK (com Dart)3.xCliente mobile
PostgreSQL16 ou superiorBase de dados
Dockerversão estável atualBase de dados local e empacotamento
Android Studio / Xcodeconforme a plataforma alvoEmulador, simulador e build mobile
Gitversão estável atualVersionamento

Verificando a instalação

Os comandos abaixo são executáveis e não alteram nada: cada um apenas responde com uma versão. Rode todos antes da próxima aula.

node --version # v22.x ou superior
npm --version
git --version
docker --version
flutter --version # inclui a versão do Dart

O Flutter traz um diagnóstico próprio, que verifica SDK, emuladores e dependências de cada plataforma:

flutter doctor
Confirme as versões no início do semestre

Node, NestJS, Next.js e Flutter têm ciclos de release rápidos. As versões acima são o ponto de partida; a combinação efetivamente adotada na turma é confirmada em aula e no Moodle.

Editor

Qualquer editor serve, mas vale garantir três coisas: suporte a TypeScript (nativo no VS Code e nos IDEs JetBrains), extensão do Flutter/Dart e um cliente HTTP para exercitar a API — Postman, Insomnia, a extensão REST Client ou simplesmente curl. A partir do Módulo 2, testar um endpoint fora do cliente web será rotina.


Erros comuns

ErroConsequência
Escolher a estratégia mobile por preferência pessoalA decisão não sobrevive à primeira revisão técnica
Adotar arquitetura desacoplada com um cliente sóPaga-se o custo da separação sem receber o benefício
Colocar regra de negócio no servidor Next.jsO cliente mobile fica sem ela: a regra deixa de existir para metade dos usuários
Tratar PWA e híbrido como sinônimosSão coisas distintas: um é site, o outro é aplicativo com WebView dentro
Supor que cross-platform elimina conhecimento de plataformaPermissões, build e publicação continuam sendo específicos de cada sistema
Começar pelos clientes, antes do contratoCada cliente inventa um contrato diferente, e os dois são refeitos
Ignorar flutter doctorO problema aparece na aula do Módulo 4, quando já não há tempo
Comparar frameworks só por desempenhoCusto de manutenção pesa mais no ciclo de vida do produto

Exercícios (Checkpoints)

  1. Explique, em duas frases, a diferença essencial entre arquitetura acoplada e desacoplada em termos do que trafega na rede — sem citar nomes de frameworks.

  2. Liste três custos concretos que a arquitetura desacoplada impõe e, para cada um, descreva em que situação esse custo não compensa.

  3. Descreva o que efetivamente desenha a interface na tela em cada uma das quatro estratégias mobile e explique como isso determina o desempenho de cada uma.

  4. Escolha uma estratégia para cada cenário, justificando com pelo menos dois critérios: (a) o aplicativo de uma revista, essencialmente texto e imagem, com uma equipe web de três pessoas; (b) um jogo casual com animação contínua; (c) o aplicativo de um banco, com biometria e leitura de código de barras; (d) uma ferramenta interna de registro de ponto, para cem funcionários.

  5. Compare Flutter e React Native quanto ao modo de renderizar a interface, e explique uma consequência prática dessa diferença para quem usa o aplicativo.

  6. Justifique por que, nesta disciplina, o backend é construído antes dos clientes. Depois, descreva o que aconteceria se os dois clientes fossem desenvolvidos em paralelo, sem contrato definido.

  7. Analise a afirmação: "Como o servidor Next.js roda no servidor, posso colocar a regra de negócio nele." Aponte por que ela é problemática na arquitetura da disciplina e o que se perde ao seguir esse caminho.

  8. Prepare o ambiente: instale Node.js, Git e o Flutter SDK, execute flutter doctor e registre o que o diagnóstico apontou. Traga as pendências para a próxima aula.

  9. Investigue um aplicativo que você usa diariamente e tente identificar a estratégia com que foi construído — observando animações, tempo de resposta, aparência entre Android e iOS, tamanho do binário. Registre as evidências e o grau de confiança da sua conclusão.


Referências

Principais

Aprofundamento