Eu estou nessa indústria de software há mais de duas décadas. Lembro-me vividamente da era do SOAP e do XML, onde a simples tarefa de fazer dois sistemas conversarem parecia exigir um exército de consultores, WSDLs complexos e uma paciência quase infinita para depurar envelopes de texto verbosos. A chegada do REST, com sua simplicidade baseada em HTTP e JSON, foi como uma lufada de ar fresco. De repente, a comunicação entre serviços se tornou mais intuitiva, mais leve e, francamente, mais agradável. Por anos, o REST reinou supremo, tornando-se o padrão de fato para a construção de APIs.

Mas o tempo passa e a tecnologia não para. O que era revolucionário ontem, hoje é o "arroz com feijão". Nos últimos anos, surgiram dois novos desafiantes ao trono do REST, cada um com uma filosofia distinta: GraphQL e gRPC. E com eles, uma nova guerra santa começou a ser travada em blogs, conferências e discussões de arquitetura. O debate geralmente gira em torno de uma única métrica: a performance.

Recentemente, me deparei com um artigo acadêmico interessante, "Performance evaluation of microservices communication with REST, GraphQL, and gRPC", de Muhammad Niswar e seus colegas. O estudo faz exatamente o que o título promete: coloca os três protocolos lado a lado e mede seu desempenho em um ambiente de microsserviços. É o tipo de conteúdo que adoro analisar, não apenas pelos resultados, mas pelo que ele não diz.

Benchmarks são fascinantes. Eles nos dão números, gráficos e uma sensação de certeza objetiva. Mas, na minha experiência, confiar cegamente neles é um erro perigoso. A escolha de uma tecnologia de comunicação vai muito além de milissegundos de latência ou percentuais de uso de CPU. É uma decisão que molda sua arquitetura, a dinâmica da sua equipe e a sua capacidade de evoluir no futuro.

Um parênteses: Já viram como é cheio de vídeo e artigos de influencers de tecnologia comparando benchmark de IA pra dizer o quanto melhorou e como uma IA é melhor que a outra? Isso é tudo besteira. Farei um artigo sobre isso em breve.

Neste artigo, vamos usar esse estudo como ponto de partida. Vamos dissecar os resultados, claro. Mas, mais importante, vamos olhar para além dos números. Vamos questionar o cenário, discutir o "custo humano" de cada abordagem e tentar entender a verdadeira história por trás da batalha das APIs. Porque a performance é importante, mas é apenas o começo da conversa.

Apresentando os três competidores

Antes de mergulharmos nos resultados do estudo, é fundamental que todos estejamos na mesma página. Se você já conhece bem os três, sinta-se à vontade para pular para a próxima seção. Mas um rápido alinhamento nunca é demais.

  • REST (Representational State Transfer): O veterano, o padrão universal. Introduzido por Roy Fielding em sua tese de doutorado em 2000, o REST não é um protocolo, mas um estilo arquitetural que usa os padrões existentes do HTTP. A comunicação é baseada em recursos (como /users/123), verbos HTTP (GET, POST, PUT, DELETE) e, geralmente, troca dados via JSON. Sua beleza está na simplicidade e na onipresença. Qualquer desenvolvedor com acesso a um navegador ou a uma ferramenta como o cURL pode interagir com uma API REST sem grandes dificuldades.
  • GraphQL (Graph Query Language): O especialista em consultas. Criado pelo Facebook para resolver seus próprios desafios com dados complexos em aplicativos móveis, o GraphQL é uma linguagem de consulta para APIs. Sua principal vantagem é dar ao cliente o poder de pedir exatamente os dados de que precisa, e nada mais. Em vez de múltiplos endpoints (como em REST), o GraphQL geralmente expõe um único endpoint que aceita consultas complexas. Isso resolve os problemas clássicos do REST de over-fetching (receber mais dados do que o necessário) e under-fetching (precisar fazer múltiplas chamadas para obter todos os dados).
  • gRPC (Google Remote Procedure Call): O velocista focado em performance. Desenvolvido pelo Google, o gRPC é um framework de RPC (Chamada de Procedimento Remoto) de código aberto e alto desempenho. Ele foi projetado para a comunicação eficiente entre serviços, especialmente em arquiteturas de microsserviços. Suas duas principais características são o uso do protocolo HTTP/2 e a definição de contratos de serviço através de Protocol Buffers (protobufs). Os protobufs permitem serializar dados em um formato binário compacto, e o HTTP/2 oferece recursos avançados como multiplexação (várias requisições em uma única conexão) e streaming bidirecional, o que o torna extremamente rápido.

Esses são os nossos três competidores. Um é o padrão estabelecido, o outro é o flexível focado no cliente, e o terceiro é o especialista em performance. Agora, vamos ver como eles se saíram no teste.

O que o estudo realmente nos diz?

O estudo de Niswar et al. construiu um sistema de microsserviços em Golang, com um serviço de autenticação e dois serviços para buscar dados: um para "dados planos" (o perfil de um professor) e outro para "dados aninhados" (o perfil do professor com todo o seu histórico educacional). Eles usaram um banco de dados MySQL para armazenamento persistente e um cache com Redis para acelerar as leituras. A carga foi gerada com o Apache JMeter, simulando de 100 a 500 requisições simultâneas.

As duas métricas principais foram tempo de resposta e utilização de CPU. E os resultados foram bastante claros.

O tempo de resposta

Quando se trata de velocidade pura, o gRPC foi o vencedor indiscutível em quase todos os cenários.

Ao buscar dados planos, com 100 requisições, o gRPC teve um tempo médio de resposta de 233 ms. O REST veio em um distante segundo lugar com 1.113 ms, e o GraphQL foi o mais lento, com impressionantes 3.852 ms. A diferença é enorme. Conforme a carga aumentava para 500 requisições, a distância se mantinha: gRPC com 2.606 ms, REST com 4.009 ms e GraphQL com 21.148 ms. A Figura 8 do artigo ilustra isso de forma muito clara.

A história foi parecida ao buscar dados aninhados, que é um cenário mais complexo e realista. Com 100 requisições, o REST foi surpreendentemente o mais rápido com 5.201 ms, seguido de perto pelo gRPC com 5.667 ms. O GraphQL novamente ficou em último, com 8.510 ms. No entanto, com 500 requisições, o gRPC assumiu a liderança com 14.962 ms, enquanto o REST ficou com 16.646 ms e o GraphQL disparou para 29.734 ms. A Figura 9 do artigo mostra essa dinâmica.

A conclusão aqui é direta: se a sua única métrica de sucesso for o tempo de resposta, o gRPC é o seu campeão. O motivo, como o próprio artigo aponta, é o HTTP/2. A capacidade de multiplexar requisições sobre uma única conexão TCP e o uso de um protocolo binário eficiente dão ao gRPC uma vantagem de performance que o HTTP/1.1 do REST e GraphQL simplesmente não consegue igualar.

Mas velocidade tem um preço.

O custo oculto da performance: a utilização de CPU

Aqui é onde a história fica mais interessante e a escolha deixa de ser tão óbvia. A performance não é de graça; ela consome recursos de máquina, e o principal deles é a CPU.

Para dados planos, o REST e o gRPC mostraram um consumo de CPU modesto e muito similar, começando em torno de 10% para 100 requisições e subindo para cerca de 48% (REST) e 36% (gRPC) com 500 requisições. O GraphQL, por outro lado, foi uma história completamente diferente. Ele começou com um uso de CPU de 120% já com 100 requisições, chegando a 142% com 500 requisições. A Figura 10 do artigo é chocante.

Se você está se perguntando como é possível usar mais de 100% da CPU, a resposta é simples: o sistema tem múltiplos núcleos de processamento. Um valor acima de 100% indica que o processo está consumindo o equivalente a mais de um núcleo de CPU inteiro.

Para dados aninhados, a tendência se manteve. O gRPC foi o mais eficiente, partindo de 30% e chegando a 84% de uso de CPU. O REST ficou no meio, indo de 38% a 123%. E o GraphQL novamente consumiu uma quantidade enorme de recursos, começando em 134% e atingindo um pico de 177% com 500 requisições. A Figura 11 ilustra esse cenário.

O que esses números nos dizem? Que a flexibilidade do GraphQL tem um custo computacional altíssimo. A necessidade de analisar uma consulta complexa, resolver os diferentes campos (potencialmente de fontes de dados distintas) e construir a resposta sob demanda exige muito mais do processador do que simplesmente servir um recurso pré-definido (REST) ou deserializar uma mensagem binária de um procedimento conhecido (gRPC).

Isso tem implicações diretas no custo da sua infraestrutura. Um serviço GraphQL sob alta carga vai exigir máquinas mais potentes ou mais instâncias para escalar, impactando diretamente a sua conta da cloud no final do mês.

Mas performance é tudo?

É aqui que eu gosto de dar um passo para trás e colocar meu chapéu de crítico. O estudo é bem executado e seus resultados são valiosos. Mas o mundo real é muito mais bagunçado do que um ambiente de laboratório.

1. Onde está o gargalo real?

O estudo utilizou um cache em Redis, o que significa que a maioria das leituras era extremamente rápida, vindo diretamente da memória. Isso coloca todo o peso da performance na camada de comunicação da API. Mas e se o gargalo não for a rede, e sim um banco de dados lento, uma consulta SQL mal otimizada ou a chamada a um serviço de terceiros? Nesses cenários, a vantagem de milissegundos do gRPC pode ser completamente ofuscada pelos segundos de espera do banco de dados. A performance de um sistema é determinada pelo seu elo mais fraco.

  1. A experiência do desenvolvedor (DX)

Benchmarks não medem o quão fácil, produtivo ou agradável é trabalhar com uma tecnologia. E, no longo prazo, a produtividade da sua equipe é um fator de custo muito mais significativo do que alguns dólares a mais na conta da AWS.

  • REST: É trivial de depurar. Qualquer pessoa pode usar cURL, Postman ou até mesmo o navegador para inspecionar uma chamada. A barreira de entrada é praticamente zero. A desvantagem é a necessidade de documentação externa (como OpenAPI/Swagger) e o versionamento, que pode se tornar um pesadelo.
  • gRPC: A abordagem contract-first com protobufs é excelente para a comunicação interna entre microsserviços. Garante que cliente e servidor estejam sempre em sincronia. No entanto, o protocolo binário é opaco. Você não pode simplesmente "olhar" o tráfego de rede para depurar. Ferramentas como o grpcurl ajudam, mas não é tão simples quanto o REST. Além disso, o passo de geração de código, embora automatizado, adiciona uma camada de complexidade ao build.
  • GraphQL: Para equipes de frontend, o GraphQL é um sonho. Ele permite que eles iterem rapidamente, ajustando as consultas de dados sem precisar pedir alterações no backend. O schema funciona como uma documentação viva e tipada. A experiência de usar ferramentas como o Apollo Client é fantástica. No entanto, o lado do servidor é complexo. O famoso problema do "N+1" (onde uma consulta simples no GraphQL pode gerar um número excessivo de consultas no banco de dados) é uma armadilha real que exige soluções sofisticadas como o DataLoader.
  1. Não existe bala de prata

A verdadeira pergunta não é "qual é o melhor?", mas sim "qual é o melhor para este problema específico?".

  • Precisa expor uma API pública para terceiros? O REST ainda é a escolha mais segura e universal. Sua simplicidade e o vasto ecossistema de ferramentas o tornam a opção padrão.
  • Precisa de comunicação de altíssima performance e baixa latência entre microsserviços internos? O gRPC foi literalmente projetado para isso. A rigidez dos contratos e a eficiência do HTTP/2 brilham nesse cenário.
  • Tem um ecossistema de clientes complexo (ex: múltiplos aplicativos web e mobile) com requisitos de dados que mudam constantemente? O GraphQL pode dar uma autonomia incrível para as equipes de frontend e otimizar o uso de dados em redes móveis.

A escolha de uma tecnologia é um trade-off. O gRPC troca a simplicidade de depuração pela performance. O GraphQL troca a simplicidade do backend pela flexibilidade do frontend. O REST troca a eficiência e a flexibilidade pela simplicidade universal.

E o resto do universo?

É importante lembrar que o mundo da comunicação entre serviços não se resume a esses três. Existem outras abordagens que merecem ser mencionadas, pois podem ser a solução ideal para certos problemas.

  • tRPC: Para quem vive no ecossistema TypeScript, o tRPC é uma alternativa fascinante. Ele permite criar APIs totalmente tipadas, de ponta a ponta, sem a necessidade de geração de código ou schemas. A segurança de tipos é inferida diretamente do código do servidor para o cliente, o que proporciona uma experiência de desenvolvimento incrível para projetos full-stack em TypeScript.
  • Comunicação assíncrona (filas de mensagens): O estudo, e toda a nossa discussão até agora, focou em comunicação síncrona (requisição-resposta). Mas muitos processos em sistemas distribuídos não precisam de uma resposta imediata. Para esses casos, usar um message broker como RabbitMQ ou Kafka é muito mais resiliente e escalável. Em vez de uma chamada direta, um serviço publica um evento, e outros serviços o consomem quando puderem. Isso desacopla os serviços e os torna mais resistentes a falhas.
  • WebSockets: Quando você precisa de comunicação bidirecional e em tempo real (como em um chat, um dashboard de monitoramento ou um jogo online), o padrão requisição-resposta do HTTP não é ideal. Os WebSockets mantêm uma conexão persistente entre cliente e servidor, permitindo que ambos enviem dados a qualquer momento.

A caixa de ferramentas de um bom engenheiro é vasta. Saber que existem martelos diferentes é o primeiro passo para não tratar tudo como um prego.

O fator humano e a cultura de engenharia

Como eu disse no início, a escolha de uma tecnologia como essa é também uma decisão cultural. Ela reflete e reforça os valores da sua equipe de engenharia.

  • Adotar o gRPC para comunicação interna sinaliza uma cultura que valoriza contratos explícitos, performance e uma clara separação de responsabilidades entre os serviços.
  • Apostar no GraphQL indica uma cultura que busca empoderar as equipes de frontend, promovendo autonomia e agilidade na camada de apresentação.
  • Manter o REST como padrão pode significar uma cultura que preza pela simplicidade, pela estabilidade e por uma baixa barreira de entrada para novos desenvolvedores.

Não há resposta certa ou errada aqui. O importante é que a decisão seja consciente. Como já discuti em outros artigos aqui no blog sobre a aplicação de IA no desenvolvimento de software e dicas de programação, as ferramentas que escolhemos têm um impacto profundo na forma como pensamos e colaboramos.

Por fim, qual API devo escolher?

Se você chegou até aqui esperando uma resposta definitiva, sinto muito em desapontar. A verdade, como quase sempre em engenharia de software, é: depende.

O estudo de Niswar e seus colegas é uma excelente contribuição. Ele nos mostra, com dados claros, os trade-offs de performance entre REST, GraphQL e gRPC. O gRPC é o rei da velocidade de resposta. O REST (e o gRPC) são muito mais eficientes em termos de CPU do que o GraphQL. O GraphQL, apesar de mais lento e custoso, oferece uma flexibilidade inigualável para o cliente.

Esses são fatos importantes. Mas são apenas uma peça do quebra-cabeça.

A decisão final deve levar em conta a sua arquitetura, o seu produto, o conhecimento da sua equipe e, talvez o mais importante, a cultura que você quer construir. Não se deixe levar apenas pela última moda ou pelo benchmark mais impressionante. Entenda os fundamentos, pese os prós e os contras no seu contexto e faça uma escolha informada.

A verdadeira pergunta que devemos nos fazer não é "qual é a ferramenta mais rápida?", mas sim: "qual ferramenta moldará nossa equipe, nossa arquitetura e nosso produto da maneira que desejamos para os próximos cinco anos?".

A resposta para isso não está em nenhum benchmark. Está na sua visão como engenheiro.