Talvez você não precise de GraphQL

3 de setembro de 2026 · 13 min de leitura

Read in english

O GraphQL é uma linguagem de consulta de dados que surgiu originalmente no Facebook, em 2012. A proposta dela é bastante interessante: condensar chamadas de API e evitar o envio de dados desnecessários.

Vamos imaginar um caso real, uma rede social, como o Instagram. Para obter os comentários de uma postagem, o frontend primeiro faz uma requisição ao endpoint /p/{id_postagem}/comments, e com base na resposta, para cada usuário, faz uma requisição ao endpoint /u/{id_usuario}. Isso para mostrar o username e a imagem de perfil de quem comentou.

Quanto maior o número de comentários, maior o número de usuários, e assim, o número de chamadas cresce rapidamente.

A sacada do GraphQL é concentrar várias consultas em uma só, e ao mesmo tempo, não puxar dados irrelevantes, economizando processamento e tráfego de rede. Com ele, a consulta pode ser descrita assim:

query ObterComentariosDaPostagem($id_postagem: ID!) {
  comentarios(id_postagem: $id_postagem) {
    id
    texto
    num_respostas
    num_curtidas
    usuario {
      id
      username
      img_perfil
    }
  }
}

Produzindo a seguinte resposta:

[
  {
    // campos vindos da entidade Comentário
    "id_comentario": 610808,
    "texto_comentario": "Ao vencedor, as batatas.",
    "num_respostas": 2,
    "num_curtidas": 23,
    "id_usuario": 34269523,

    // campos vindos da entidade Usuário
    "username": "machado_de_assis",
    "img_perfil": "https://i.instacdn.com/user_34269523.jpg"
  },
  // ...
]

Dessa forma, a consulta obtém em uma só resposta os comentários e os dados dos usuários. Se for necessário puxar mais campos de informação, basta especificá-los na query.

Dificuldades de implementação

Apesar de seus benefícios, o GraphQL impõe alguns empecilhos.

O primeiro é o acoplamento à camada de dados. A maioria dos bancos de dados não tem suporte nativo a GraphQL, de modo que para fazer essas consultas, precisa ser construída nas APIs uma camada de mappers e queries por cima de uma camada já existente de acesso a dados. Além do esforço de desenvolvimento, há um gasto extra de processamento.

O segundo ponto é a segurança da informação. Como o cliente pode definir os campos que deseja, deve haver uma higienização e validação da query antes da execução, a fim de impedir acesso lateral a dados não-autorizados.

Terceiro ponto: não há suporte no GraphQL a funções agregadoras (somas, contagens, médias). No caso de estudo acima, se num_curtidas e num_respostas forem contagens nas tabelas Curtidas e Comentários, esses valores terão de ser calculados via código no banco de dados ou na API.

Questionamentos

O GraphQL foi feito para atender uma pluralidade de clientes com necessidades distintas. Por exemplo: o app mobile precisa obter os dados de um jeito, o frontend web de outro, o back office de outro. Em companhias grandes, como é o caso do Facebook, a adoção do GraphQL pode fazer sentido, considerando ainda que há muitas integrações com terceiros (B2B, analytics, anúncios, etc.).

Não havendo essa pluralidade de clientes, ou ainda, se alguns poucos endpoints conseguem atender bem a maioria das necessidades, o GraphQL perde a atratividade.

Alternativas

Condensação de consultas

A condensação de múltiplas consultas pode ser feita via código nas APIs ou através de enlaces, tanto em bancos SQL como NoSQL. No caso anterior de obter comentários de uma postagem, dá para fazer através de JOINs em SQL.

SELECT
  cm.[Id],
  cm.[Texto],
  COUNT(DISTINCT cm_resp.[Id]) AS [NumRespostas],
  COUNT(DISTINCT cu.[Id]) AS [NumCurtidas],
  cm.[IdUsuario],
  u.[Username],
  u.[ImgPerfil]
FROM [dbo].[Comentarios] cm
LEFT JOIN [dbo].[Comentarios] cm_resp ON cm_resp.[IdPai] = cm.[Id]
LEFT JOIN [dbo].[Curtidas] cu ON cu.[IdComentario] = cm.[Id]
INNER JOIN [dbo].[Usuario] u ON u.[Id] = cm.[IdUsuario]
WHERE cm.[IdPostagem] = @idPostagem
GROUP BY cm.Id, cm.Texto, cm.IdUsuario, u.Username, u.ImgPerfil

A consulta pode parecer complexa, mas é a solução mais eficiente em termos de performance.

Em sistemas de alta performance, NumRespostas e NumCurtidas provavelmente seriam campos dentro da própria entidade Comentário e os valores seriam incrementados após cada comentário-resposta ou curtida. O exemplo acima é para demonstrar agregações.

Campos opcionais

As APIs podem receber flags em que o cliente indica se deseja receber ou não um determinado campo.

Imagine uma empresa de logística que tenha um serviço para listar os fretes realizados por um motorista, no endpoint /motorista/{id_motorista}/viagens. O cliente indica o nível de detalhe através de um query parameter:

  • ?nivelDetalhe=resumido
[
  {
    "de": "Fazenda Capela do Bosque",
    "para": "CEAGESP São Paulo",
    "partida": "2022-08-04T06:10:04",
    "chegada": "2022-08-04T07:48:15",
    "status": "Concluída",
  },
  // ...
]
  • ?nivelDetalhe=completo
[
  {
    "de": "Fazenda Capela do Bosque",
    "enderecoDe": "Estrada da Glória, 1000, Porto Feliz - SP", 
    "para": "CEAGESP São Paulo",
    "enderecoPara": "Av. Dr. Gastão Vidigal, 1946, São Paulo - SP", 
    "partida": "2022-08-04T06:10:04",
    "chegada": "2022-08-04T07:48:15",
    "status": "Concluída",
    "cargaConteudo": "Ovos", 
    "cargaPesoLiquidoKg": 14300, 
    // ...
  },
  // ...
]

Outra opção é ter flags granulares:

?incluirEnderecos=true&incluirCarga=true

O que não for especificado não será consultado e incluído na resposta.

HTTP/2 e HTTP/3

O HTTP/2 e o HTTP/3 conseguem juntar vários fluxos de dados em um mesmo pacote TCP ou UDP, optimizando tráfego de rede.

Retomando o exemplo acima, de frete de carga; se quisermos obter dados do motorista, talvez não faça sentido incluir esses campos dentro do objeto JSON de viagem, então, precisaremos fazer uma chamada separada. Se HTTP/2 ou HTTP/3 forem usados, as respostas dos endpoints /motorista/{id_motorista}/viagens e /motorista/{id_motorista} podem chegar juntas em um único pacote de rede.

Confira mais sobre HTTP/2 e HTTP/3 funcionam neste artigo.

A

AlexandreHTRB

Campinas / SP,
Brasil