What is GraphQL? A Practical Introduction for Testers
GraphQL lets the client decide what data to fetch. Here's how it works and when it beats REST.
GraphQL in one sentence
GraphQL is a query language for APIs that lets clients ask for exactly the fields they need, in one request, instead of calling multiple REST endpoints and throwing away most of the response.
Created at Facebook in 2012, open-sourced in 2015, now used by GitHub, Shopify, Netflix, and many others. Not a replacement for REST — a different tool with different trade-offs.
The single-endpoint model
A REST API has many endpoints. A GraphQL API has one: typically POST /graphql. You send a query in the request body describing what you want, and the server returns exactly that shape.
{
user(id: "abc-123") {
name
email
posts(limit: 5) {
title
createdAt
}
}
}
Response:
{
"data": {
"user": {
"name": "Alice",
"email": "alice@example.com",
"posts": [
{ "title": "Hello world", "createdAt": "2026-05-01T..." }
]
}
}
}
Note what you didn't do: you didn't call /users/abc-123 and then /users/abc-123/posts. One round-trip, exact fields, no over-fetching.
Try it
/graphqlcurl -X POST 'https://demo.totalshiftleft.ai/graphql' \
-H 'Content-Type: application/json' \
-d '{"query":"{ users(limit: 5) { items { id name email role } pageInfo { total } } }"}'Change the query. Ask for fewer fields — the response shrinks. Ask for more — the server returns them. The client drives the shape.
Queries vs mutations
GraphQL has three operation types:
- Query — read data. Like GET in REST.
- Mutation — write data (create, update, delete). Like POST/PUT/PATCH/DELETE.
- Subscription — long-lived connection for real-time updates. Like WebSockets.
Mutations look like queries but are prefixed with mutation:
/graphqlcurl -X POST 'https://demo.totalshiftleft.ai/graphql' \
-H 'Content-Type: application/json' \
-d '{"query":"mutation { createUser(input: { name: \"GraphQL Bob\", email: \"bob@graphql.com\" }) { id name email } }"}'Mutations also return a shape you specify — you decide what fields of the created/updated resource come back.
The schema
A GraphQL API is defined by a schema: a strongly-typed description of every type, field, query, and mutation. Schemas are written in the GraphQL Schema Definition Language (SDL):
type User {
id: ID!
name: String!
email: String!
role: UserRole
posts(limit: Int = 10): [Post!]!
}
type Query {
users(limit: Int, sort: String): UserConnection!
user(id: ID!): User
}
type Mutation {
createUser(input: CreateUserInput!): User!
}
! means non-nullable. Types with ! after them are guaranteed present; types without can be null.
The schema is self-documenting. Tools can introspect any GraphQL endpoint and generate docs, SDKs, and tests automatically. Open /graphql in a browser on any GraphQL API — you usually get an interactive explorer called GraphiQL.
What GraphQL solves
- Over-fetching — REST returns full objects; GraphQL returns only requested fields.
- Under-fetching / N+1 requests — fetch user + posts + comments in one request instead of many.
- Versioning — instead of
/v1/and/v2/, you add fields (never breaking clients) and deprecate old ones with annotations. - Typed client code — schemas enable auto-generated, type-safe SDKs in every language.
What GraphQL is bad at
- Caching — REST GETs cache trivially by URL. GraphQL everything-is-POST breaks HTTP caching; you need a dedicated cache layer (Apollo, Relay).
- File uploads — no standard way. Workarounds exist but are awkward.
- Error handling — returns 200 with
errorsin the body. Breaks tools that expect HTTP status codes to reflect success/failure. - Learning curve — schema, resolvers, DataLoaders, fragments, directives — more concepts than REST.
- Performance ceiling — a poorly-written query can ask for everything and bring down the server.
What testers should know
Testing GraphQL is different enough from REST that it deserves its own guide (see how to test GraphQL APIs). Headlines:
- You still assert on HTTP 200 for a valid request — but check the
errorsarray too. - Your test queries should be minimal — ask only for the fields you assert on, to keep tests fast and focused.
- Mutations that fail validation often return 200 with errors; don't rely solely on HTTP status.
- Schema changes can break clients silently; contract testing is essential.
When to use GraphQL
Good fit:
- Mobile clients with bandwidth constraints (exact-field fetching saves a lot).
- Dashboards that aggregate data from many sources into one view.
- APIs with many client types (web, mobile, smart TV) — each picks the fields it needs.
Bad fit:
- Simple CRUD APIs with one client. REST is easier.
- File-heavy APIs (uploads, downloads).
- APIs where HTTP caching is important (public content APIs, especially).
What's next
Now dig into queries vs mutations in depth, or compare protocols side-by-side in REST vs GraphQL vs gRPC testing.
Frequently asked questions
What is GraphQL API testing?+
GraphQL API testing sends queries and mutations, usually to a single POST /graphql endpoint, and checks that the response has the requested shape and no errors. It differs from REST testing because a valid request returns HTTP 200 even when the body contains an errors array.
What are GraphQL testing best practices?+
Assert HTTP 200 and also check the errors array, because failed mutations often return 200. Keep test queries minimal by requesting only the fields you assert on, and use contract testing, since schema changes can break clients silently.
What is GraphQL introspection used for in testing?+
Introspection lets tools read a GraphQL API's schema, which describes every type, field, query, and mutation. Because the schema is self-documenting and strongly typed, tools can introspect an endpoint and generate docs, SDKs, and tests automatically.
Related lessons
Queries read. Mutations change state. Here's the divide — and how to write both correctly.
REST is the default API style on the web. Here's what it actually means — stripped of jargon and with runnable examples.
SOAP isn't dead — it runs banks, insurance, and government. Here's how it actually works.
Read more on the blog
How to test GraphQL APIs — the real differences from REST testing, working code in the frameworks you already use, and the tools built specifically for GraphQL exploration and testing.
How testing changes between REST, GraphQL and gRPC, and where SOAP fits: contract formats, error semantics, security surface, mocking, observability and tooling, with the same check written in each protocol.