REST vs GraphQL vs tRPC: Como Escolher a Arquitetura da Tua API
A Febre do GraphQL: Como uma Promessa de Simplicidade Trouxe Complexidade
Em 2016, o mundo do desenvolvimento web foi inundado pelo entusiasmo em torno do GraphQL. Criado pela Meta para substituir o REST, prometia resolver dois problemas clássicos: o over-fetching (receber cinquenta campos da base de dados quando só precisavas do primeiro nome) e o under-fetching (fazer três pedidos seguidos para obter o perfil, as encomendas e as moradas).
Equipas inteiras deitaram fora os seus endpoints REST e reescreveram tudo em GraphQL.
Passados alguns anos, o entusiasmo inicial deu lugar a uma ressaca técnica:
- A Cache de HTTP Foi Destruída: Como todas as pesquisas do GraphQL viajam como pedidos
POSTpara um único endereço (/graphql), os proxies de borda como o Nginx e as CDNs deixaram de conseguir guardar respostas em cache. Os clientes foram obrigados a instalar bibliotecas pesadas como o Apollo Client, acrescentando 45KB de código JavaScript ao browser. - O Problema das Consultas N+1: Listar 40 artigos e os respetivos autores resultava em 41 consultas separadas à base de dados SQL, exigindo camadas complexas de empacotamento com o
DataLoader. - Ataques de Consultas Profundas: Qualquer utilizador podia enviar consultas com ciclos infinitos (
utilizador { amigos { amigos { amigos ... } } }), esgotando a memória do servidor num piscar de olhos.
O CICLO DE SOBRE-ENGENHARIA DO GRAPHQL
-
- Adotar GraphQL para resolver o over-fetching
-
- Perder a cache de HTTP na borda (Tudo passa por POST /graphql)
-
- Sofrer com problemas N+1 na BD (Obriga a programar DataLoaders)
-
- Adicionar Apollo Client pesado (Mais 45KB de bundle no telemóvel!)
- Programar limitadores de profundidade contra ataques de DoS (Resultado: Uma arquitetura frágil e 5 vezes mais difícil de manter!)
Para manteres as tuas aplicações fiéis aos princípios de anti-over-engineering, precisas de analisar de forma pragmática as três opções reais do mercado: REST, GraphQL e tRPC.
A Revolução do tRPC: Tipagem Total Sem Esquemas Nem Compilações
Nos dias de hoje, uma enorme percentagem dos projetos digitais é construída em TypeScript de ponta a ponta: interfaces em React, Astro ou Next.js a comunicar com servidores em Fastify ou Node.js dentro de um monorepo partilhado.
Neste cenário moderno, tanto o REST como o GraphQL obrigam a um trabalho redundante:
- No REST, tens de escrever especificações em Swagger/OpenAPI e gerar tipos.
- No GraphQL, tens de manter ficheiros
.graphqle correr ographql-codegen.
O tRPC (TypeScript Remote Procedure Call) elimina esse desperdício aproveitando a inferência natural do próprio compilador de TypeScript:
INFERÊNCIA DE TIPOS DE PONTA A PONTA COM TRPC
- Router no Backend (Fastify / Express): export const appRouter = router({ obterUtilizador: publicProcedure
- .input(z.object({ id: z.string() }))
- .query(async ({ input }) => ({ id: input.id, nome: “Ana”, perfil: “admin” })) export type AppRouter = typeof appRouter; // Exporta APENAS o tipo estático! (0 bytes)
- (Tipagem Automática sem Compilação no Monorepo)
- Frontend na Tua Aplicação Web: const { data } = trpc.obterUtilizador.useQuery({ id: “89” });
- // data.nome é automaticamente uma string!
- // data.perfil é automaticamente “admin”!
- // ZERO GERAÇÃO DE CÓDIGO! AUTO-COMPLETE PERFEITO NO EDITOR!
Com o tRPC, não partilhas código compilado nem bibliotecas pesadas entre frontend e backend. Partilhas apenas o tipo estático type AppRouter. Se mudares o nome de um campo na base de dados de nome para nomeCompleto, o teu editor de código assinala imediatamente a vermelho as linhas afetadas no frontend em tempo real!
Como Criar uma Rota com Validação Segura no tRPC
Vê como podes estruturar uma rota simples e robusta no tRPC combinada com a biblioteca de validação Zod:
// src/server/routers/encomendaRouter.ts
import { router, publicProcedure } from '../trpc.js';
import { z } from 'zod';
import { db } from '../../db/postgres.js';
export const encomendaRouter = router({
// Consulta validada com tipagem rigorosa
obterPorId: publicProcedure
.input(
z.object({
encomendaId: z.string().uuid(),
})
)
.query(async ({ input }) => {
const resultado = await db.query(
'SELECT id, valor_total, estado FROM encomendas WHERE id = $1',
[input.encomendaId]
);
if (!resultado.rows[0]) {
throw new Error('Encomenda não encontrada');
}
return resultado.rows[0];
}),
// Mutação para gravação de novos registos
criarEncomenda: publicProcedure
.input(
z.object({
artigos: z.array(z.object({ sku: z.string(), quantidade: z.number().min(1) })),
cupao: z.string().optional(),
})
)
.mutation(async ({ input }) => {
// Processa a compra...
return { sucesso: true, id: 'enc_4502' };
}),
});
No teu frontend, chamar esta função é tão natural como chamar uma função local, acelerando o desenvolvimento das tuas web apps.
Onde o REST Tradicional Continua a Ser Imbatível
Apesar do sucesso do tRPC, o REST clássico continua a ser a escolha certa em três cenários incontornáveis:
- APIs Públicas para Clientes Externos: Se estás a desenhar uma API para ser consumida por clientes em Python, Android, iOS nativo ou PHP, o tRPC não serve porque exige TypeScript. O REST com OpenAPI é a linguagem universal de programação.
- Cache Agressiva na Borda da Rede: Uma rota RESTful como
GET /api/v1/catalogo/destaquespode ser guardada em cache no Nginx e na Cloudflare com cabeçalhosCache-Control: public, max-age=3600. A resposta é entregue em 2 milissegundos sem nunca acordar o teu servidor backend. - Envio de Ficheiros Pesados: Fazer uploads de fotos ou vídeos por multipart HTTP é limpo e eficiente em REST, ao passo que tentar passar binários dentro de mutations de GraphQL ou tRPC exige conversões lentas em Base64.
- CACHE NA BORDA: REST vs GRAPHQL / TRPC
- Pedido REST Tradicional: GET /api/v1/produtos → [Cache Nginx / Cloudflare: RESPOSTA EM 2ms!] (Zero carga no servidor! Velocidade máxima para websites de alta performance)
- Pedido GraphQL ou tRPC: POST /graphql → Bypassa a cache padrão de HTTP da borda (Obriga sempre a executar código no servidor backend!)
Esta facilidade de cache torna o REST insubstituível na construção de websites de alta performance.
Matriz de Decisão: REST vs GraphQL vs tRPC
Para escolheres a melhor solução técnica segundo os padrões da WebXtek, consulta esta matriz comparativa:
MATRIZ DE DECISÃO TÉCNICA
| CRITÉRIO | REST (OpenAPI) | GRAPHQL | TRPC |
|---|---|---|---|
| Tipo de Equipa | Várias Linguagens | Equipas Grandes / Múlt | TypeScript Full-Stack |
| Segurança de Tipos | Manual ou Codegen | Esquema com Codegen | Automática e Imediata |
| Cache Nativa de HTTP | Perfeita e Imediata | Muito Complexa | Por URL de Consulta |
| Peso no Cliente | Zero (Fetch nativo) | Alto (Apollo Client) | Mínimo (< 2KB) |
| Complexidade Backend | Baixa e Previsível | Alta (DataLoaders) | Baixa (Funções puras) |
| Melhor Aplicação | APIs Públicas / Media | Grandes Redes Heterog. | SaaS Rápido / B2B |
Podes analisar projetos com Docker e exemplos de código no repositório de suporte no GitHub.
Boas Práticas Operacionais: Consultas Persistidas e Padronização de Erros
Seja qual for a tecnologia que escolheres no teu projeto, deves aplicar estas três regras de engenharia:
- Nunca Deixes o GraphQL Aberto ao Público: Se precisares de usar GraphQL, ativa o mecanismo de consultas persistidas (Persisted Queries). Os clientes registam as consultas autorizadas durante o deploy e o servidor bloqueia qualquer código arbitrário enviado em tempo de execução.
- Gera Documentação OpenAPI a Partir do tRPC: Se usares tRPC mas mais tarde precisares de partilhar endpoints com parceiros externos, podes usar o pacote
trpc-openapi, que gera a documentação do Swagger automaticamente sem duplicares rotas. - Padroniza as Respostas de Erro: Usa a norma internacional RFC 7807 (Problem Details) para devolveres erros com formato uniforme em todas as rotas da tua aplicação.
Ao escolheres a arquitetura da tua API com base em necessidades reais e não nas modas passageiras das redes sociais, evitas complexidade desnecessária e entregas uma aplicação rápida, escalável e fácil de manter.
Na prática, aplicas exatamente estes padrões operacionais em setores exigentes como saas empresarial b2b e especialistas em devops e arquitetura cloud. Quando alinhas a tua estrutura através de web apps e websites de alta performance, transformas boas práticas técnicas numa vantagem competitiva real e mensurável para o teu negócio.
[+] [ INDEX_DIRECTORY ] 14 tópicos ▼
- A Febre do GraphQL: Como uma Promessa de Simplicidade Trouxe Complexidade
- A Revolução do tRPC: Tipagem Total Sem Esquemas Nem Compilações
- Como Criar uma Rota com Validação Segura no tRPC
- Onde o REST Tradicional Continua a Ser Imbatível
- Matriz de Decisão: REST vs GraphQL vs tRPC
- Boas Práticas Operacionais: Consultas Persistidas e Padronização de Erros
- Autor
- Perguntas Frequentes
- Qual é a diferença fundamental entre REST, GraphQL e tRPC?
- Porque é que o GraphQL não substituiu o REST como muitos previam?
- Quando é que o tRPC é a melhor escolha técnica?
- O REST tradicional ainda faz sentido em projetos modernos?
- Nós Relacionados
- Sequência do Caminho
Perguntas Frequentes
Qual é a diferença fundamental entre REST, GraphQL e tRPC?
O REST disponibiliza URLs fixos associados a verbos HTTP. O GraphQL usa um único endpoint POST flexível onde o cliente escolhe os campos exatos. O tRPC oferece tipagem estrita de ponta a ponta em TypeScript sem esquemas manuais nem passos de compilação de código.
Porque é que o GraphQL não substituiu o REST como muitos previam?
O GraphQL quebra a cache nativa de HTTP (como a do Nginx e CDNs), cria problemas graves de consultas N+1 na base de dados (exigindo bibliotecas pesadas como DataLoader), aumenta o peso do JavaScript no cliente e expõe o backend a ataques de exaustão de consultas profundas.
Quando é que o tRPC é a melhor escolha técnica?
O tRPC é imbatível quando desenvolves aplicações full-stack com TypeScript (como Next.js, Astro ou Fastify) onde a mesma equipa controla o frontend e o backend num monorepo. Elimina completamente a necessidade de sincronizar tipos e documentar endpoints manuais.
O REST tradicional ainda faz sentido em projetos modernos?
Sim. O REST continua a ser a melhor opção para APIs públicas acessíveis por várias linguagens (Python, apps móveis nativas) e sistemas com alto volume de tráfego que dependem da cache nativa de HTTP nas bordas da rede.
[ RELATED_NODES ]
> INICIAR_PROJETO
Precisa de um website que transmita confiança, apareça na pesquisa e dê mais força à sua presença digital? Comece a conversa aqui.