## glossary
What is GraphQL?
GraphQL is a query language for APIs created at Facebook in 2012 and released publicly in 2015. Its core proposal is to flip who decides the shape of the response: instead of the server defining what each endpoint returns, it is the client that describes the fields it wants to receive.
The motivation was practical. Facebook’s mobile app needed less data than the web version, but both consumed the same endpoints — resulting in responses far too large for phones and in several chained calls to assemble a single screen.
A query and its response
# query
{
usuario(id: "42") {
nome
posts(ultimos: 2) {
titulo
}
}
}
# response
{
"data": {
"usuario": {
"nome": "Ana",
"posts": [
{ "titulo": "Introdução a testes" },
{ "titulo": "Refatorando legado" }
]
}
}
}Notice two things. First, the response has exactly the shape of the question — nothing more. Second, the user and their posts came together, in a single round trip to the network; in REST that would normally take two calls.
The problems GraphQL solves
- Over-fetching — receiving fields the screen never uses, wasting bandwidth. With GraphQL, you ask only for what you need.
- Under-fetching — needing several chained calls to assemble one screen. A single query resolves the whole graph.
- Endpoint proliferation — every new screen demanding a tailor-made endpoint. The schema is single and flexible.
- Stale documentation — the schema is typed and introspectable, so documentation is generated from the code itself.
Schema, queries and mutations
Every GraphQL API starts with a schema: the typed declaration of which data exists and how it relates. Queries read data; mutations change it; and subscriptions keep an open channel to receive real-time updates. Unlike REST, all of this travels through a single endpoint, usually /graphql.
type Usuario {
id: ID!
nome: String!
posts: [Post!]!
}
type Query {
usuario(id: ID!): Usuario
}
type Mutation {
criarPost(titulo: String!, autorId: ID!): Post!
}The costs that come with it
GraphQL is not free in complexity. Caching stops being trivial, because there is no distinct URL per resource for HTTP to cache. A poorly written query can trigger the N+1 problem, generating hundreds of database queries. And since the client controls the shape of the query, you need to limit depth and complexity to prevent a malicious query from taking down the server. For simple, stable APIs, a REST API usually delivers the same result with fewer moving parts.
## faq
Frequently asked questions
Does GraphQL replace REST?
Not necessarily. GraphQL makes sense when there are many clients with different data needs or complex relationships between entities. For small, public APIs or ones that rely heavily on HTTP caching, REST remains the simpler choice and often the better one.
Which HTTP method does GraphQL use?
Almost always POST, to a single endpoint. That happens because the query travels in the request body. Some implementations accept GET with the query in the URL, which allows HTTP caching, but URL length limits restrict its use.
What is the N+1 problem in GraphQL?
It is when resolving a list of N items fires one database query per item, plus the original query — N+1 in total. The standard solution is DataLoader, which batches the requests made within the same execution cycle into a single bulk query.