REST and GraphQL solve the same problem in opposite ways. With REST you call many URLs and take whatever each one returns. With GraphQL you call one URL and state exactly which fields you want back. That single difference changes how you test it.
One endpoint, many queries
A REST API spreads its surface across dozens of paths. A GraphQL API exposes a single
endpoint — usually /graphql — and the request body decides what happens. There are no
resource URLs to memorise; there is a schema of types, and you ask for a shape carved
out of it.
That means the interesting variation in your tests lives in the request body, not the URL. A GraphQL test suite is a set of queries against one endpoint, not a set of endpoints.
Send your first query
Point SchemaClient's GraphQL panel at the endpoint and send a query:
query {
user(id: "42") {
name
email
}
}
You get back exactly those fields and nothing else:
{
"data": {
"user": { "name": "Ada", "email": "ada@example.com" }
}
}
Ask for a field that does not exist and the server rejects the whole query before
running it — a class of typo that a REST API would happily return as undefined.
Variables keep queries reusable
Do not paste changing values into the query text. Pass them as variables, so the same query works for every input:
query GetUser($id: ID!) {
user(id: $id) {
name
email
}
}
{ "id": "42" }
This is the GraphQL equivalent of parameterising a REST request, and it is what lets you save one query in a collection and reuse it instead of editing text every time.
Mutations change data
Writing data uses the same mechanism with the mutation keyword:
mutation UpdatePlan($id: ID!, $plan: String!) {
updateUser(id: $id, plan: $plan) {
id
plan
}
}
Ask the mutation to return the fields it changed, so you can confirm the write in the same round-trip instead of firing a second query to check.
The 200 OK trap
Here is the part that catches everyone coming from REST. A GraphQL endpoint typically
answers 200 OK even when your query failed. The failure is described in an errors
array alongside — or instead of — data:
{
"data": null,
"errors": [{ "message": "User 42 not found" }]
}
A test that only asserts on the status code passes here while the query returned
nothing. You have to assert on the body: check that errors is absent and that data
holds what you expected. This is the same failure mode described in
why a 200 OK response can still be broken, just built
into the protocol by design.
Use introspection instead of guessing
You do not need a copy of the schema to start. Most GraphQL servers answer an introspection query that describes their own types and fields, and SchemaClient uses it to offer autocomplete as you type. Point it at an unfamiliar endpoint and the available fields appear — far faster than reading documentation that may be out of date.
Validate the response shape
Once a query is stable, lock its shape in with
schema validation. GraphQL guarantees the
types of fields you asked for, but it does not stop a resolver returning null where
your app expects a value, and nullability is where GraphQL responses most often break
consumers. Assert on it rather than trusting it.
New to API testing generally? Start with how to test a REST API — the request-and-inspect loop is the same, only the request body differs.