GraphQL contra REST: qual tecnologia escolher para um projeto JavaScript em 2024?

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

GraphQL vs REST: um duelo que deveria ter começado ontem

\n\n

Situação familiar: você está escrevendo um novo projeto em JavaScript (ou Node.js), e de repente surge a pergunta: o que usar para a comunicação entre frontend e backend? O clássico REST ou o moderno GraphQL? Os debates sobre esse assunto não param, e cada desenvolvedor tem sua opinião "de ferro".

\n\n

Vamos ser honestos: REST é aquele velho amigo de confiança que nunca decepciona. GraphQL é o novato ousado que promete resolver todos os seus problemas. Mas como escolher? Vou mostrar não apenas tabelas de comparação secas, mas exemplos reais de combate em JavaScript. Você verá como o código se parece, onde surgem as armadilhas e, o mais importante, quando usar cada um.

\n\n

A propósito, se você desenvolve em Python (e este site é sobre Python, não se esqueça), os princípios de escolha entre essas tecnologias são muito semelhantes. Mas hoje estamos falando de JavaScript — a linguagem que domina tanto no cliente quanto no servidor.

\n\n

Guia rápido: REST e GraphQL em 60 segundos

\n\n

REST (Representational State Transfer)

\n

É um estilo arquitetural onde cada recurso (usuário, postagem, comentário) tem sua própria URL. Você faz uma requisição GET para /api/users/1 — obtém o usuário. Quer as postagens dele? Vá para /api/users/1/posts. Tudo simples, previsível, mas... às vezes muito verboso.

\n\n

GraphQL

\n

É uma linguagem de consulta e ambiente de execução. Você tem um único endpoint (geralmente /graphql) e decide quais dados deseja obter. Sem over-fetching (quando chegam 50 campos, mas você precisa de 3) e sem under-fetching (quando precisa fazer 5 requisições para montar uma página).

\n\n

Comparação prática: escrevendo código em JavaScript

\n\n

Vamos imaginar uma tarefa típica: exibir na página o perfil de um usuário com suas três últimas postagens. Vamos comparar ambas as abordagens.

\n\n

Exemplo de API REST com Express (Node.js)

\n\n
// Servidor REST com Express\nconst express = require('express');\nconst app = express();\n\napp.get('/api/users/:id', (req, res) => {\n  // Retorna TODOS os dados do usuário\n  const user = users.find(u => u.id === req.params.id);\n  res.json(user); // { id, name, email, phone, address, ... }\n});\n\napp.get('/api/users/:id/posts', (req, res) => {\n  // Retorna TODAS as postagens do usuário\n  const posts = posts.filter(p => p.userId === req.params.id);\n  res.json(posts); // [{ id, title, body, createdAt, ... }]\n});\n\n// Código do cliente (frontend com fetch)\nasync function loadProfile(userId) {\n  // Primeira requisição — obtém o usuário (vem muita coisa desnecessária)\n  const userResponse = await fetch(`/api/users/${userId}`);\n  const user = await userResponse.json();\n  \n  // Segunda requisição — obtém as postagens (novamente dados extras)\n  const postsResponse = await fetch(`/api/users/${userId}/posts`);\n  const allPosts = await postsResponse.json();\n  \n  // Pega apenas as 3 últimas postagens\n  const latestPosts = allPosts.slice(0, 3);\n  \n  return { user, posts: latestPosts };\n}
\n\n

O problema é óbvio: recebemos muitos dados desnecessários (over-fetching). Para que precisamos de email, phone, address, se estamos mostrando apenas o nome e o avatar? E podem haver 100 postagens, mas precisamos de apenas 3.

\n\n

Exemplo de GraphQL com Apollo Server (Node.js)

\n\n
// Esquema GraphQL\nconst typeDefs = `\n  type User {\n    id: ID!\n    name: String\n    avatar: String\n    posts(limit: Int): [Post]\n  }\n\n  type Post {\n    id: ID!\n    title: String\n    body: String\n  }\n\n  type Query {\n    user(id: ID!): User\n  }\n`;\n\n// Resolvers (lógica de obtenção de dados)\nconst resolvers = {\n  Query: {\n    user: (parent, { id }) => users.find(u => u.id === id),\n  },\n  User: {\n    posts: (parent, { limit }) => {\n      let result = posts.filter(p => p.userId === parent.id);\n      if (limit) result = result.slice(0, limit);\n                

Blogs

Book Recommendations