REST é um estilo de API com vários endpoints fixos; GraphQL é uma linguagem de consulta em que o cliente pede a um único endpoint só os campos de que precisa. A comparação é, no fundo, sobre quem decide o formato da resposta: no REST, o servidor decidiu em tempo de design; no GraphQL, o cliente decide a cada requisição. Todo o resto — cache, versionamento, erros, performance — decorre dessa única inversão.
Principais pontos
| Pergunta | Resposta |
|---|---|
| REST | Muitos endpoints, respostas definidas pelo servidor, cache nativo do HTTP |
| GraphQL | Um endpoint, schema tipado, campos e aninhamento selecionados pelo cliente |
| A vitória do GraphQL | Overfetching e underfetching morrem; um round trip por tela |
| A vitória do REST | Cache de CDN, simplicidade, suporte universal |
| A realidade de 2026 | Coexistência — REST em todo lugar, GraphQL como camada de agregação do frontend |
A mesma tela, dos dois jeitos
Uma tela de perfil precisa de um usuário, seus cinco posts mais recentes e a contagem de seguidores. REST fala em recursos:
GET /users/42 → 38 campos, você precisava de 3 (overfetching)
GET /users/42/posts?limit=5 → segundo round trip (underfetching)
GET /users/42/followers → terceiro round trip
GraphQL fala em uma única pergunta moldada:
POST /graphql
query {
user(id: 42) {
name
avatarUrl
posts(first: 5) { title likes }
followers { totalCount }
}
}
→ um round trip, exatamente esses campos, nada mais
A distância é menor do que as manchetes sugerem: um REST bem projetado também suporta seleção de campos — e os query builders dos SDKs a tornam um hábito de primeira classe:
// JavaScript / Node.js — Back4app JS SDK
// GraphQL's best trick — ask only for what you need — without leaving REST
const query = new Parse.Query('Article');
query.equalTo('status', 'published');
query.select('title', 'views'); // field selection, GraphQL-style
const articles = await query.find(); // lean payload over the REST API
// The same backend also speaks real GraphQL: query { articles { ... } } // Flutter / Dart — Back4app Flutter SDK
// GraphQL's best trick — ask only for what you need — without leaving REST
final query = QueryBuilder<ParseObject>(ParseObject('Article'))
..whereEqualTo('status', 'published')
..keysToReturn(['title', 'views']); // field selection, GraphQL-style
final response = await query.query(); // lean payload over the REST API // iOS / Swift — Back4app Swift SDK
// GraphQL's best trick — ask only for what you need — without leaving REST
let query = Article.query("status" == "published")
.select("title", "views") // field selection, GraphQL-style
query.find { result in
if case .success(let articles) = result { render(articles) }
} // Android / Kotlin — Back4app Android SDK
// GraphQL's best trick — ask only for what you need — without leaving REST
val query = ParseQuery.getQuery<ParseObject>("Article")
query.whereEqualTo("status", "published")
query.selectKeys(listOf("title", "views")) // field selection, GraphQL-style
query.findInBackground { articles, e -> if (e == null) render(articles) } GraphQL vs. REST em resumo
| Dimensão | REST | GraphQL |
|---|---|---|
| Endpoints | Muitos, no formato de recursos | Um, no formato do schema |
| Formato da resposta | Definido pelo servidor | Selecionado pelo cliente a cada query |
| Tipagem | Convenção (OpenAPI opcional) | Imposta pelo schema, introspectável |
| Round trips | Um por recurso | Um por tela |
| Cache | Nativo de HTTP/CDN, indexado por URL | Normalizado no cliente; persisted queries |
| Versionamento | /v1 → /v2 | Evoluir + deprecar, sem versões |
| Erros | Status codes HTTP | 200 + array de errors, resultados parciais |
| Tempo real | Separado (webhooks, sockets) | Subscriptions na spec |
| Curva de aprendizado | Mínima | Schema, resolvers, controle de custo |
| Melhor primeiro encaixe | CRUD público, cacheável e simples | Frontends multi-cliente, densos em dados |
As partes que as páginas de comparação pulam
O problema N+1 mudou de endereço, não morreu. Uma query GraphQL de posts-com-autores dispara, ingenuamente, uma chamada de resolver por post — a mesma patologia N+1 que os ORMs tornaram famosa, agora no lado do servidor. A cura padrão é batching: um loader por requisição coleta os IDs de autor e os busca em uma única query. Adotar GraphQL sem estratégia de batching é adotar o pior bug de performance do REST em um endereço novo.
Erros são uma decisão de operações. “200 com um array de errors” significa que dashboards, alertas e lógica de CDN construídos sobre status codes ficam cegos por padrão. Times que prosperam com GraphQL tratam a observabilidade de erros como parte da adoção, não como um adendo.
Queries sem limites precisam de limites. Um endpoint flexível significa que uma query pode atravessar o grafo inteiro — a orientação oficial de segurança é limite de profundidade, orçamento de custo de query e allowlists de persisted queries para clientes first-party. Os endpoints fixos do REST tornavam o controle de custo implícito; o GraphQL o torna trabalho seu.
Casos de uso comuns
- GraphQL: apps mobile em redes lentas, dashboards costurando muitas entidades, produtos com clientes web + mobile + parceiros divergindo em necessidades de dados, iteração rápida de frontend contra um schema estável.
- REST: APIs públicas para desenvolvedores, entrega de conteúdo cacheável, superfícies de webhook e integração, transferência de arquivos, chamadas serviço-a-serviço em que a simplicidade vence.
- Os dois (a norma enterprise): REST ou RPC entre serviços de backend; uma camada GraphQL agregando-os para os frontends — o padrão backend-for-frontend com um schema.
GraphQL ou REST? Matriz de decisão
| Escolha REST quando… | Escolha GraphQL quando… | Use os dois quando… |
|---|---|---|
| Terceiros consomem a API | Telas costuram muitos recursos | Serviços falam REST, frontends querem formatos |
| Cache de CDN carrega a carga | Clientes diferem nos dados de que precisam | Uma API pública e um frontend de produto coexistem |
| Recursos mapeiam 1:1 para telas | Overfetching dói para usuários mobile | Você migra incrementalmente |
| O time entrega esta semana | Contratos tipados aceleram o frontend | Times diferentes são donos de camadas diferentes |
| Arquivos e webhooks dominam | Subscriptions em tempo real são centrais | Você prefere não reabrir esse debate |
O padrão honesto: comece com REST, adicione GraphQL quando a dor de moldar dados para múltiplos clientes realmente chegar — e, se a sua plataforma gera os dois a partir de um só schema, a escolha deixa de ser arquitetural e passa a ser por requisição.
Limitações e trade-offs
- REST: over/underfetching em telas densas de dados, migrações de versão, deriva do formato das respostas entre times e N endpoints de documentação.
- GraphQL: cache exige maquinaria, controle de custo exige vigilância, resolvers exigem disciplina de batching e o padrão 200-com-errors exige retrabalho de observabilidade.
- Os dois: nenhum conserta um modelo de dados ruim — um domínio confuso produz uma API confusa em qualquer estilo, como a própria dissertação do REST quietamente sugere: as restrições sempre foram sobre a arquitetura por baixo.
GraphQL e REST no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. Ele dissolve o dilema deste artigo pela raiz: os dois estilos de API são gerados a partir do mesmo schema — endpoints REST cacheáveis por URL e uma API GraphQL tipada com queries aninhadas — mais SDKs cuja seleção de campos (as abas de código acima) entrega o benefício-manchete do GraphQL sobre qualquer um dos dois transportes. Escolha por cliente, troque por tela e nunca escreva a camada de API.
Perguntas frequentes
Qual é a principal diferença entre GraphQL e REST?
O formato do contrato. REST expõe muitos endpoints de recursos, cada um retornando uma resposta definida pelo servidor — você recebe o que o endpoint entrega. GraphQL expõe um único endpoint com um schema tipado, e cada cliente escreve uma query nomeando exatamente os campos e as relações aninhadas que quer. REST fixa as respostas no servidor; GraphQL move essa decisão para o cliente.
GraphQL é mais rápido que REST?
Para telas que precisam de dados de vários recursos, geralmente sim — uma query substitui múltiplos round trips e o payload carrega só os campos pedidos. Para um único recurso simples, REST costuma ser mais rápido, porque suas respostas indexadas por URL cacheiam lindamente em CDNs. E resolvers mal escritos podem deixar o GraphQL mais lento que qualquer coisa, via problema N+1. A carga de trabalho decide.
O que são overfetching e underfetching?
As duas dores do REST que o GraphQL nasceu para resolver. Overfetching: um endpoint retorna o recurso inteiro quando a tela precisa de três campos. Underfetching: uma chamada não basta, então o cliente faz N requisições extras por dados relacionados. Seleção de campos e queries aninhadas atacam as duas — por isso apps densos em dados e multi-cliente sentem primeiro a atração pelo GraphQL.
GraphQL está substituindo o REST?
Não — os dados da indústria dizem coexistência. Pesquisas mostram consistentemente a esmagadora maioria dos times usando REST, com cerca de um terço usando GraphQL, na maior parte ao lado do REST e não no lugar dele. O padrão enterprise dominante é híbrido: REST (ou RPC) entre serviços e em APIs públicas, com GraphQL como camada de agregação servindo os clientes de frontend.
Como o cache difere entre REST e GraphQL?
Respostas REST vivem em URLs únicas, então navegadores e CDNs as cacheiam sem esforço algum — seu superpoder silencioso. GraphQL tipicamente envia POSTs a um único endpoint, o que quebra o cache indexado por URL; o ecossistema compensa com caches normalizados no cliente e persisted queries sobre GET. Cache é o argumento mais forte a favor do REST em APIs públicas de leitura pesada.
Como o versionamento difere?
REST versiona explicitamente — um v2 na URL ou no header — e roda as duas versões durante migrações. GraphQL mira a evolução sem versões: adicione campos livremente, marque os antigos como deprecated, observe a telemetria de uso e remova-os quando os clientes pararem de pedir. Os dois funcionam; GraphQL troca a cerimônia de versões pela disciplina de governança de schema.
Como os erros diferem entre os dois?
REST se apoia em status codes HTTP — um 404 é visível para todo proxy, monitor e biblioteca de cliente. GraphQL costuma retornar 200 com um array de errors ao lado de dados parciais, o que habilita sucesso parcial, mas significa que o monitoramento precisa parsear corpos de resposta em vez de confiar em status codes. É uma diferença operacional real, não uma nota de rodapé.
Quando você ainda deveria escolher REST?
Gatilhos concretos: APIs públicas consumidas por muitos terceiros, tráfego de leitura fortemente cacheável, CRUD simples no formato de recursos, upload e download de arquivos, integrações no estilo webhook e times sem experiência operacional com GraphQL. REST é o padrão que tudo suporta; GraphQL é o especialista que você contrata para frontends multi-cliente e densos em dados.