GraphQL API
A real GraphQL endpoint with a small user schema behind it. Query it from the built-in tester below, or from Postman, Insomnia, or your automation framework, and see where testing GraphQL differs from testing REST.
Where you'll meet GraphQL
GraphQL sits in front of data the same way REST does, but everything goes through a single endpoint and the client decides which fields it wants back. You will meet it most often in mobile apps and single-page apps, where trimming response size matters, and in large public APIs. GitHub and Shopify both expose their main APIs over GraphQL.
For a tester the biggest shift is error handling. A GraphQL server usually answers with HTTP 200 even when the query fails, and puts the real signal in an errors array in the response body. Your assertions have to read the body, not the status code.
Endpoint
https://practise.assertqa.com/api/graphqlEverything goes through this one URL. Only POST is implemented; any other method returns 405 Method Not Allowed. OPTIONS is available for CORS preflight requests. What you get back is decided by the query in the request body, not by the URL.
Headers
Content-Typeapplication/jsonRequest Body
querystringrequired- •The GraphQL document to execute, sent as a plain string
variablesobject- •Values for any $variables declared in the query
operationNamestring- •Which operation to run when the document contains more than one
{
"query": "query GetUser($id: ID!) { user(id: $id) { name email } }",
"variables": { "id": "4" }
}Schema
The full schema definition. GraphQL-aware clients can also load it automatically through introspection.
type User {
id: ID!
name: String!
email: String!
role: String!
active: Boolean!
}
type Query {
health: String!
users(role: String): [User!]!
user(id: ID!): User
}
input RegisterUserInput {
name: String!
email: String!
password: String!
}
type RegisteredUser {
name: String!
email: String!
}
type RegisterUserPayload {
success: Boolean!
message: String!
errors: [String!]!
user: RegisteredUser
}
type Mutation {
registerUser(input: RegisterUserInput!): RegisterUserPayload!
}Try It Live
Pick an example or write your own query, then send a real request to the endpoint straight from your browser. The raw response and status code appear in the terminal.
ExamplesSend a request to see the response here.Possible Responses
The query executed. The response contains exactly the fields you asked for, nothing more.
{
"data": {
"users": [
{ "name": "Marko Jovanovic", "active": true },
{ "name": "Jelena Nikolic", "active": false }
]
}
}The query failed: an unknown field, broken syntax, or a bad variable. The status code is still 200, so the errors array in the body is the only signal.
{
"errors": [
{
"message": "Cannot query field \"nickname\" on type \"User\". Did you mean \"name\"?",
"locations": [{ "line": 1, "column": 11 }]
}
]
}The request body isn't valid JSON, or it has no query string at all.
{
"errors": [
{ "message": "Request body must contain a \"query\" string." }
]
}Sent with any method other than POST or OPTIONS.
{
"errors": [
{ "message": "Method not allowed. GraphQL requests must use POST." }
]
}Scenarios to Test
Use these as a starting checklist, then come up with your own. Most GraphQL bugs hide in the gap between what the status code says and what the body says.
Query Basics
- Fetch all users and check the shape of data.users in the response.
- Request only name and active, then confirm no other fields appear in the response. Picking fields is the core GraphQL feature REST doesn't have.
- Rename a field with an alias, e.g. { people: users { name } }, and assert on data.people.
- Query the health field alongside users in a single request. One round trip, two resources.
Error Handling
- Query a field that doesn't exist (e.g. nickname) and note the status is still 200 OK.
- Send a query with broken syntax and read the errors array. How precisely does it point to the problem?
- Send valid JSON with no query key at all and compare: this one is a 400.
- Write an assertion that would catch a failing query even though the status code says everything is fine.
Arguments & Variables
- Fetch user id 4 with an inline argument, then again with a $id variable. Confirm both return the same data.
- Ask for an id that doesn't exist. You get data.user: null and no error. Is that the behavior you'd expect?
- Declare $id as ID! but send no variables. What error comes back, and with which status code?
- Filter users by role and verify every returned user matches. Then try a role that doesn't exist.
Mutations
- Register a valid user and confirm success, message, and the returned user object.
- Send an invalid registration and note where the validation errors live: inside data.registerUser.errors, not the top-level errors array.
- Leave out a required input field like password. Now the error is top-level, because the schema rejects the request before any code runs. Compare the two failure modes.
- Run the same valid mutation twice. Does anything change between runs? What does that tell you about persistence?
Testing a GraphQL API on a real product?
This sandbox is a safe place to practice, but production GraphQL APIs carry real risk, and failures often hide behind a 200 status. Our API testing services validate REST and GraphQL endpoints by hand and in automated suites, with every bug logged with the exact request and response to reproduce it.
Need expert QA help? We offer team training, automation consulting, and end-to-end QA services.
Need this tested professionally?
Building or testing a GraphQL API for real? AssertQA delivers test automation services, manual testing services, and API testing services for teams that need real-world quality.