---
term: 'GraphQL'
seoTitle: 'O que é GraphQL? Linguagem de Consulta, Schema e Resolvers'
headline: 'O que é GraphQL?'
slug: graphql
category: api-realtime
shortDefinition: 'GraphQL é uma linguagem de consulta para APIs e um runtime server-side que retorna exatamente os campos que cada cliente pede em uma única requisição.'
relatedTerms:
  - graphql-vs-rest
  - rest-api
  - overfetching-underfetching
  - auto-generated-database-apis
contrastsWith:
  - rest-api
aboutTerms:
  - 'Schema GraphQL (SDL)'
  - 'Resolver GraphQL'
  - 'Mutations e Subscriptions GraphQL'
faq:
  - question: 'O que é GraphQL em termos simples?'
    answer: 'Uma linguagem de consulta que permite ao cliente pedir a uma API exatamente os campos de que precisa — relações aninhadas incluídas — em uma única requisição, mais um runtime de servidor que atende esses pedidos a partir das suas fontes de dados existentes. Ele fica na frente de qualquer banco de dados ou serviço; não é um banco de dados em si.'
  - question: 'GraphQL é melhor que REST?'
    answer: 'Nenhum dos dois é universalmente melhor. GraphQL vence com clientes diversos, restrições de banda e dados agregados de várias fontes; REST vence em cache HTTP, simplicidade e maturidade de ferramental para CRUD no formato de recursos. O padrão dominante em produção é pragmático: uma camada GraphQL para os frontends sobre internals REST ou RPC.'
  - question: 'GraphQL é um banco de dados ou algo como SQL?'
    answer: 'Não — é uma linguagem de API na camada de aplicação, agnóstica de armazenamento por design: resolvers podem ler de qualquer banco de dados, de outra API ou de um arquivo. E, apesar do nome, não é uma linguagem genérica de consulta a grafos como SPARQL; você percorre o grafo apenas pelos caminhos que o schema expõe.'
  - question: 'O que são queries, mutations e subscriptions?'
    answer: 'Os três tipos de operação. Queries leem dados; mutations escrevem — e retornam o novo estado no mesmo round trip, então o cliente se atualiza sem uma busca adicional; subscriptions empurram atualizações em tempo real por uma conexão persistente, tipicamente WebSockets. As três são validadas contra o mesmo schema.'
  - question: 'O que é um schema GraphQL?'
    answer: 'O contrato tipado entre cliente e servidor, escrito na Schema Definition Language: os tipos de objeto, seus campos e os pontos de entrada raiz Query, Mutation e Subscription. Toda operação que chega é validada contra ele antes da execução, e o ferramental o introspecta para gerar documentação e clientes tipados.'
  - question: 'O que é um resolver?'
    answer: 'Uma função server-side que busca o valor de um campo — de um banco de dados, de outra API, de qualquer lugar. O runtime percorre cada query e chama o resolver de cada campo solicitado, o que é ao mesmo tempo a flexibilidade do GraphQL e a origem do seu problema N+1, quando os resolvers de itens de lista consultam um a um.'
  - question: 'GraphQL só funciona sobre HTTP POST?'
    answer: 'Pela especificação, GraphQL é agnóstico de transporte; na prática, é servido em um único endpoint HTTP — por convenção /graphql — geralmente via POST com corpo JSON, com GET permitido para queries e WebSockets carregando as subscriptions. Uma especificação de GraphQL sobre HTTP agora padroniza essas convenções.'
  - question: 'Quando NÃO usar GraphQL?'
    answer: 'CRUD simples de recursos com clientes uniformes, tráfego de leitura que o cache HTTP e de CDN absorveria, transferência pesada de arquivos e times pequenos sem apetite para batching de resolvers, limitação por custo de query e governança de schema. Nesses casos, uma API REST bem projetada é menos maquinaria para o mesmo resultado.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'GraphQL Specification (October 2021 edition)'
    url: 'https://spec.graphql.org/October2021/'
  - name: 'Introduction to GraphQL — graphql.org'
    url: 'https://graphql.org/learn/'
  - name: 'GraphQL over HTTP specification (working draft)'
    url: 'https://graphql.github.io/graphql-over-http/'
  - name: 'DataLoader — batching for the N+1 problem'
    url: 'https://github.com/graphql/dataloader'
  - name: 'GraphQL — Wikipedia'
    url: 'https://en.wikipedia.org/wiki/GraphQL'
cta:
  title: 'Uma API GraphQL sem escrever resolvers'
  text: 'Todo modelo de dados no Back4app vem com um schema GraphQL gerado automaticamente — queries, mutations e connections tipadas prontas para uso, permissões aplicadas a cada requisição, console GraphQL incluído.'
  linkText: 'Comece grátis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-08-20'
translationKey: graphql
---

**GraphQL é uma linguagem de consulta para APIs e um runtime server-side que retorna exatamente os campos que cada cliente pede em uma única requisição.** A dualidade importa: a *linguagem* é uma [especificação](https://spec.graphql.org/October2021/) que qualquer cliente pode falar; o *runtime* executa essas queries contra um sistema de tipos que você define sobre os dados que já tem — qualquer banco, qualquer serviço. GraphQL não é um banco de dados, e não substitui nem o seu armazenamento nem, necessariamente, a sua [API REST](/glossary/pt/api-rest/).

## Principais pontos

| Pergunta | Resposta |
| --- | --- |
| O que é | Uma linguagem de consulta governada por spec + runtime de execução — agnóstica de armazenamento |
| O movimento característico | O formato da resposta espelha o da query: peça campos, receba esses campos |
| As três operações | query (leitura) · mutation (escrita) · subscription (push em tempo real) |
| Os blocos de construção | Schema (contrato SDL) · tipos · resolvers (funções de busca por campo) |
| A conta honesta | Estratégia de cache, batching do N+1, limites por custo, hardening de segurança |

## A demo característica: query e resposta

A demo para a qual toda explicação converge, porque ela *é* a ideia — a resposta é a query, preenchida:

```graphql
# Requisição                           # Resposta
{                                      {
  post(id: "8fk2") {                     "data": {
    title                                  "post": {
    author {                                 "title": "Hello GraphQL",
      username                               "author": {
    }                                          "username": "ada"
    comments(first: 2) {                     },
      text                                   "comments": [
    }                                          { "text": "Nice." },
  }                                            { "text": "Ship it." }
}                                            ]
                                           }
                                         }
                                       }
```

Uma requisição, três recursos relacionados, zero campos não solicitados — o par [overfetching e underfetching](/glossary/overfetching-underfetching/) aposentado de um golpe só. Chamá-la de clientes reais é HTTP puro:

**JavaScript:**

```javascript
// JavaScript / Node.js — query Back4app's auto-generated GraphQL API
const res = await fetch('https://parseapi.back4app.com/graphql', {
  method: 'POST',
  headers: {
    'X-Parse-Application-Id': APP_ID,
    'X-Parse-Client-Key': CLIENT_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: '{ posts(first: 20) { edges { node { title author { username } } } } }',
  }),
});
const { data } = await res.json(); // shaped exactly like the query
```

**Flutter:**

```dart
// Flutter / Dart — query Back4app's auto-generated GraphQL API
final res = await http.post(
  Uri.parse('https://parseapi.back4app.com/graphql'),
  headers: {
    'X-Parse-Application-Id': appId,
    'X-Parse-Client-Key': clientKey,
    'Content-Type': 'application/json',
  },
  body: jsonEncode({
    'query': '{ posts(first: 20) { edges { node { title author { username } } } } }',
  }),
);
final data = jsonDecode(res.body)['data']; // shaped exactly like the query
```

**Swift:**

```swift
// iOS / Swift — query Back4app's auto-generated GraphQL API
var request = URLRequest(url: URL(string: "https://parseapi.back4app.com/graphql")!)
request.httpMethod = "POST"
request.setValue(appId, forHTTPHeaderField: "X-Parse-Application-Id")
request.setValue(clientKey, forHTTPHeaderField: "X-Parse-Client-Key")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let query = "{ posts(first: 20) { edges { node { title author { username } } } } }"
request.httpBody = try JSONEncoder().encode(["query": query])
let (data, _) = try await URLSession.shared.data(for: request)
// data is shaped exactly like the query
```

**Kotlin:**

```kotlin
// Android / Kotlin — query Back4app's auto-generated GraphQL API
val body = """{ "query": "{ posts(first: 20) { edges { node { title author { username } } } } }" }"""
val request = Request.Builder()
    .url("https://parseapi.back4app.com/graphql")
    .addHeader("X-Parse-Application-Id", APP_ID)
    .addHeader("X-Parse-Client-Key", CLIENT_KEY)
    .post(body.toRequestBody("application/json".toMediaType()))
    .build()
val data = client.newCall(request).execute().body?.string() // shaped like the query
```

## Schema, query, resolver: o trio que faz o trabalho

As explicações mostram a query; quase nenhuma mostra a maquinaria por trás dela como um quadro coerente. O **schema** é o contrato tipado, escrito em SDL:

```graphql
type Post {
  title: String!          # ! = não nulo
  author: User!
  comments(first: Int): [Comment!]
}

type Query {              # os pontos de entrada de leitura
  post(id: ID!): Post
}

type Mutation {           # os pontos de entrada de escrita
  createPost(title: String!): Post!
}
```

**Resolvers** são a outra metade do runtime — uma função por campo, cada uma livre para buscar de onde quiser:

```js
const resolvers = {
  Query: {
    post: (_, { id }) => db.posts.findById(id),
  },
  Post: {
    author: (post) => db.users.findById(post.authorId),   // chamada por post!
  },
};
```

A execução é um pipeline: parsear a query, **validar** contra o schema (operações inválidas morrem antes de tocar em dados) e então percorrer o selection set chamando resolvers e montar o JSON espelhado. Essa chamada de resolver por campo é também o preço da flexibilidade — note o `// chamada por post!`, que vira o problema N+1 logo abaixo. O nome, que ninguém explica: seus dados formam um *grafo* de objetos tipados, e as queries o percorrem a partir dos campos raiz — mas apenas pelos caminhos expostos no schema, não em travessias arbitrárias como numa verdadeira linguagem de consulta a grafos.

Proveniência, em resumo: criado no Facebook (hoje Meta) em 2012 para seus apps mobile, aberto como open source em 2015, governado desde 2018 pela GraphQL Foundation sob a Linux Foundation, edição atual da spec de outubro de 2021, com um [draft de GraphQL sobre HTTP](https://graphql.github.io/graphql-over-http/) padronizando as convenções de transporte.

## Queries, mutations e subscriptions

```mermaid
flowchart LR
  accTitle: Pipeline de execução do GraphQL
  accDescr: Uma operação do cliente — query, mutation ou subscription — chega a um único endpoint, é parseada e validada contra o schema, executada com a chamada de um resolver por campo solicitado contra bancos de dados ou serviços, e retornada como JSON espelhando o formato da requisição.
  C["Operação do cliente<br/>query · mutation · subscription"] --> E["Endpoint único<br/>/graphql"]
  E --> V["Parse + validação<br/>contra o schema"]
  V --> R["Execução:<br/>um resolver por campo"]
  R --> D[("Bancos de dados,<br/>APIs, serviços")]
  D --> R
  R --> J["JSON espelhando<br/>o formato da query"] --> C
```

**Queries** leem. **Mutations** escrevem — e selecionam campos no resultado, então o cliente recebe o estado pós-escrita no mesmo round trip. **Subscriptions** mantêm uma conexão aberta (na prática, WebSockets) e empurram eventos conforme ocorrem; são a [história de tempo real](/glossary/websockets-real-time-sync/) do GraphQL, com a ressalva de que cada subscription ativa é estado mantido no servidor. As três compartilham o schema, o sistema de tipos e o ferramental — um contrato, três tempos verbais.

## GraphQL vs. REST

| | GraphQL | REST |
| --- | --- | --- |
| Endpoints | Um (`/graphql`) | Um por recurso |
| Formato da resposta | Composto pelo cliente a cada query | Fixo por endpoint |
| Over/underfetching | Resolvido na camada HTTP | Mitigado por parâmetros |
| Cache HTTP | Perdido por padrão (um único POST) | Nativo — o superpoder |
| Tipagem e introspecção | Embutidas no contrato | Opcionais via OpenAPI |
| Versionamento | Evolução sem versões + @deprecated | Convenções /v1, /v2 |
| Tempo real | Subscriptions na spec | Fora do escopo |
| Melhor em | Clientes diversos, dados aninhados | CRUD de recursos, leituras cacheáveis |

O argumento completo — inclusive quando REST é simplesmente a escolha melhor — está no verbete dedicado [GraphQL vs. REST](/glossary/pt/graphql-vs-rest/).

## Rodando GraphQL em produção: os custos honestos

A seção que os explicadores de vendor suavizam. **Cache:** um único endpoint POST abre mão do cache HTTP e de CDN indexado por URL; a substituição são caches normalizados no cliente, indexados por `id` mais `__typename`, e persisted queries (operações pré-aprovadas e hasheadas, enviadas como GET) para recuperar parte do cache de transporte. **N+1:** resolvers ingênuos transformam uma lista de 20 posts em 1 + 20 leituras no banco — o [mesmo problema](/glossary/n-plus-one-query-problem/) que clientes REST têm sobre HTTP, realocado para a sua camada de resolvers e corrigido lá com loaders de batching como o [DataLoader](https://github.com/graphql/dataloader). **Erros:** GraphQL retorna `200 OK` com um array `errors` — monitoramento baseado em status codes fica cego se não for reensinado. **Rate limiting:** requisições não são iguais quando uma query pode aninhar dez relações; APIs maduras medem o *custo da query* (análise de profundidade e complexidade), não a contagem de requisições. **Segurança:** desabilite a introspecção em produção, imponha limites de profundidade e complexidade e mantenha a autorização na camada de negócio, sob os resolvers — o endpoint único também cega regras de WAF baseadas em URL, então a validação se move para dentro da própria camada GraphQL.

## Casos de uso comuns

- **Apps mobile em redes limitadas** — o caso de uso fundador: campos exatos, mínimo de bytes, menos round trips.
- **Produtos multi-cliente** — app de relógio, app de celular, dashboard web, cada um moldando as próprias respostas contra um único schema.
- **Agregação backend-for-frontend** — uma camada GraphQL compondo vários serviços internos para consumo pelas UIs.
- **Frontends em evolução rápida** — telas novas selecionam campos novos sem esperar por endpoints novos.
- **Contratos tipados de ponta a ponta** — a introspecção do schema gerando clientes tipados, mantendo API e UI honestas em tempo de compilação.

## Você deveria usar GraphQL? Matriz de decisão

| GraphQL justifica sua maquinaria quando… | Prefira REST quando… |
| --- | --- |
| Clientes diferem nos dados de que precisam | Um único tipo de cliente, telas estáveis |
| Telas leem dados aninhados e relacionais | Recursos mapeiam limpo para endpoints |
| Você agrega várias fontes de backend | Um serviço é dono dos dados |
| Banda é preciosa (mobile-first) | Cache HTTP/CDN carrega a carga de leitura |
| Uma plataforma gera o schema para você | O time teria que construir e blindar tudo à mão |

## Limitações e trade-offs

- **A flexibilidade é paga pelo servidor.** Queries arbitrárias do cliente exigem que o servidor seja seguro sob qualquer formato — batching, limites de custo e guardas de profundidade são pré-requisitos, não acabamento.
- **Cache vira projeto seu.** O que o HTTP dava de graça ao REST, times de GraphQL reimplementam em caches de cliente e persisted queries.
- **Observabilidade precisa ser reaprendida.** Um endpoint só, respostas sempre-200 e timing por campo exigem ferramental que entenda GraphQL.
- **Upload de arquivos e dados binários são desajeitados** — em geral delegados a endpoints de upload separados, ao lado do grafo.
- **Governança de schema é organizacional.** Um contrato compartilhado entre times precisa de regras de ownership; federação (compor subgraphs de cada time em um supergraph) é a resposta de escala — e uma disciplina própria.

## GraphQL 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. A parte distintiva é de onde vem o schema: defina um modelo de dados e a plataforma [gera a API GraphQL](/glossary/pt/apis-geradas-automaticamente/) — tipos de objeto tipados, campos de query e mutation, connections que atravessam relações como o exemplo `posts → author` acima — sem resolvers para escrever, já que o Back4app os implementa contra o seu banco com permissões aplicadas a cada requisição. As abas de código mostram a história inteira do lado do cliente: um POST para `/graphql` com as chaves do seu app. Um console GraphQL embutido cobre a exploração, o REST continua disponível sobre os mesmos dados para leituras amigáveis a cache, e a lógica customizada entra no schema como funções de Cloud Code — a seção de custos honestos acima vira, em grande parte, conta da plataforma, não sua.
