Mocking GraphQL APIs
MockServer can mock GraphQL APIs in two complementary ways:
- Schema import — send a GraphQL SDL or introspection document to
PUT /mockserver/graphqland MockServer generates one expectation per root operation type. Matched queries receive a schema-valid, synthesized{"data": {...}}response with no hand-authored JSON required. - Explicit GraphQL expectations — write an expectation whose body matcher is a
GRAPHQLbody with a query string, operation name, or field list, giving precise control over which operations are matched and what response is returned.
GraphQL matching works on standard HTTP: a GraphQL request arrives as a POST to /graphql (or a configurable path) with the operation in the JSON body. MockServer does not require any protocol plugin — it matches and responds to GraphQL traffic using the same HTTP expectation mechanism as REST.
Schema Import — PUT /mockserver/graphql
The schema import endpoint parses a GraphQL SDL or introspection document and generates mock expectations automatically — one per root operation type (Query, Mutation, Subscription) defined by the schema.
Send the schema as the raw request body with Content-Type: application/graphql (for SDL) or Content-Type: application/json (for an introspection result):
# Import from SDL
curl -s -X PUT "http://localhost:1080/mockserver/graphql" \
-H "Content-Type: application/graphql" \
--data-raw '
type Query {
user(id: ID!): User
products(category: String): [Product]
}
type Mutation {
createOrder(input: OrderInput!): Order
}
type User { id: ID! name: String email: String }
type Product { id: ID! name: String price: Float inStock: Boolean }
type Order { id: ID! status: String total: Float }
input OrderInput { productId: ID! quantity: Int }
'
# Import from an introspection JSON result (both envelope forms are accepted)
curl -s -X PUT "http://localhost:1080/mockserver/graphql" \
-H "Content-Type: application/json" \
-d '{ "data": { "__schema": { ... } } }'
The optional ?path= query parameter overrides the default /graphql request path the generated expectations match:
curl -s -X PUT "http://localhost:1080/mockserver/graphql?path=/api/graphql" \
-H "Content-Type: application/graphql" \
--data-raw 'type Query { ping: String }'
On success, the endpoint returns 201 Created with a JSON array of the generated expectations. On a schema parse error it returns 400 Bad Request with a plain-text error message.
Schema-Driven Response Synthesis
When a matched GraphQL expectation has a schema attached — either via schema import or a schema field on a GRAPHQL body — MockServer synthesizes a schema-valid response for the actual query at request time, rather than returning a fixed stub. Only the fields the client requested appear in the response (the selection set is honoured).
Synthesis rules follow GraphQL execution semantics:
- Scalar placeholders —
String→"string",Int→0,Float→0.0,Boolean→true,ID→"id" - Enum types — the first declared value
- List types — a single-element array containing the synthesized element
- Object types — recurse into the sub-selection set
- Inline fragments and named fragment spreads — flattened into the selection set
- Non-null wrappers — unwrapped transparently
The synthesized response is wrapped in a {"data": {...}} envelope. An explicit response body on the expectation always takes precedence — schema synthesis only fires when the response body is absent.
Example: given the schema above, a client query of { user(id: "1") { name email } } produces:
{
"data": {
"user": {
"name": "string",
"email": "string"
}
}
}
GraphQL Body Matcher in Expectations
To match specific GraphQL operations, set the request body type to GRAPHQL in an expectation. The body matcher supports three match modes:
| Match mode | selectionSetMatchType |
Description |
|---|---|---|
| Normalised string (default) | NORMALISED_STRING |
Whitespace-normalised string comparison of the full query text. Use this when you want to match a known, fixed query string exactly. |
| Exact AST | AST_EXACT |
The operation type, name, and top-level field set must match exactly. |
| Subset AST | AST_SUBSET |
The expected fields must be a subset of the actual query's top-level fields. Useful when matching "any query that includes field X" regardless of what other fields are requested. |
Additional body matcher fields:
| Field | Type | Description |
|---|---|---|
query |
string | The GraphQL query/mutation/subscription string to match against. For NORMALISED_STRING mode, whitespace is normalised before comparison. |
operationName |
string | Optional exact operation name to match (plain string or regex). Only applies to named operations. |
variablesSchema |
string | Optional JSON Schema string. When set, the variables in the GraphQL request body are validated against this schema as an additional match condition. |
schema |
string | GraphQL SDL or introspection JSON to attach to this expectation. When present and the response body is absent, MockServer synthesizes a schema-valid response for the matched query. |
Explicit Expectation Examples
Match a specific query string and return an explicit response
new MockServerClient("localhost", 1080)
.when(
request()
.withMethod("POST")
.withPath("/graphql")
.withBody(
GraphQLBody.graphQL("query GetUser($id: ID!) { user(id: $id) { name email } }")
)
)
.respond(
response()
.withStatusCode(200)
.withHeader("Content-Type", "application/json")
.withBody("{\"data\":{\"user\":{\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}")
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": {
"type": "GRAPHQL",
"query": "query GetUser($id: ID!) { user(id: $id) { name email } }"
}
},
"httpResponse": {
"statusCode": 200,
"headers": { "Content-Type": ["application/json"] },
"body": "{\"data\":{\"user\":{\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}"
}
}).then(
function () {
console.log("expectation created");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse, GraphQLBody, KeyToMultiValue
client = MockServerClient("localhost", 1080)
client.when(
HttpRequest(
method="POST",
path="/graphql",
body=GraphQLBody(query="query GetUser($id: ID!) { user(id: $id) { name email } }"),
)
).respond(
HttpResponse(
status_code=200,
headers=[KeyToMultiValue(name="Content-Type", values=["application/json"])],
body='{"data":{"user":{"name":"Alice","email":"alice@example.com"}}}',
)
)
require 'mockserver-client'
client = MockServer::Client.new('localhost', 1080)
client.when(
MockServer::HttpRequest.new(
method: 'POST',
path: '/graphql',
body: MockServer::GraphQLBody.new(
query: 'query GetUser($id: ID!) { user(id: $id) { name email } }'
)
)
).respond(
MockServer::HttpResponse.new(
status_code: 200,
headers: [MockServer::KeyToMultiValue.new(name: 'Content-Type', values: ['application/json'])],
body: '{"data":{"user":{"name":"Alice","email":"alice@example.com"}}}'
)
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7"
client := mockserver.New("localhost", 1080)
client.Upsert(mockserver.Expectation{
HttpRequest: &mockserver.HttpRequest{
Method: "POST",
Path: "/graphql",
Body: mockserver.GraphQLBody("query GetUser($id: ID!) { user(id: $id) { name email } }", ""),
},
HttpResponse: &mockserver.HttpResponse{
StatusCode: 200,
Headers: map[string][]string{"Content-Type": {"application/json"}},
Body: `{"data":{"user":{"name":"Alice","email":"alice@example.com"}}}`,
},
})
using MockServer.Client;
using MockServer.Client.Models;
using var client = new MockServerClient("localhost", 1080);
client.Upsert(new Expectation
{
HttpRequest = new HttpRequest
{
Method = "POST",
Path = "/graphql",
Body = Body.OfGraphQl("query GetUser($id: ID!) { user(id: $id) { name email } }")
},
HttpResponse = new HttpResponse
{
StatusCode = 200,
Headers = new() { ["Content-Type"] = new() { "application/json" } },
Body = "{\"data\":{\"user\":{\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}"
}
});
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse, Body};
let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(
HttpRequest::new()
.method("POST")
.path("/graphql")
.body_value(Body::graphql("query GetUser($id: ID!) { user(id: $id) { name email } }")),
).respond(
HttpResponse::new()
.status_code(200)
.header("Content-Type", "application/json")
.body("{\"data\":{\"user\":{\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}"),
).unwrap();
<?php
// no typed GRAPHQL body setter — submit the raw expectation JSON via HTTP PUT
$json = '{
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": { "type": "GRAPHQL", "query": "query GetUser($id: ID!) { user(id: $id) { name email } }" }
},
"httpResponse": {
"statusCode": 200,
"headers": { "Content-Type": ["application/json"] },
"body": "{\"data\":{\"user\":{\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}"
}
}';
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_exec($ch);
curl_close($ch);
curl -s -X PUT http://localhost:1080/mockserver/expectation \
-H "Content-Type: application/json" \
-d '{
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": {
"type": "GRAPHQL",
"query": "query GetUser($id: ID!) { user(id: $id) { name email } }"
}
},
"httpResponse": {
"statusCode": 200,
"headers": { "Content-Type": ["application/json"] },
"body": "{\"data\":{\"user\":{\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}"
}
}'
See REST API for full JSON specification
Match any query that includes a specific field (subset AST)
new MockServerClient("localhost", 1080)
.when(
request()
.withMethod("POST")
.withPath("/graphql")
.withBody(
GraphQLBody.graphQL("query { user { email } }")
.withSelectionSetMatchType(SelectionSetMatchType.AST_SUBSET)
)
)
.respond(
response()
.withStatusCode(200)
.withHeader("Content-Type", "application/json")
.withBody("{\"data\":{\"user\":{\"id\":\"1\",\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}")
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": {
"type": "GRAPHQL",
"query": "query { user { email } }",
"selectionSetMatchType": "AST_SUBSET"
}
},
"httpResponse": {
"statusCode": 200,
"headers": { "Content-Type": ["application/json"] },
"body": "{\"data\":{\"user\":{\"id\":\"1\",\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}"
}
}).then(
function () {
console.log("expectation created");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse, GraphQLBody, KeyToMultiValue
client = MockServerClient("localhost", 1080)
client.when(
HttpRequest(
method="POST",
path="/graphql",
body=GraphQLBody(
query="query { user { email } }",
selection_set_match_type="AST_SUBSET",
),
)
).respond(
HttpResponse(
status_code=200,
headers=[KeyToMultiValue(name="Content-Type", values=["application/json"])],
body='{"data":{"user":{"id":"1","name":"Alice","email":"alice@example.com"}}}',
)
)
require 'mockserver-client'
client = MockServer::Client.new('localhost', 1080)
client.when(
MockServer::HttpRequest.new(
method: 'POST',
path: '/graphql',
body: MockServer::GraphQLBody.new(
query: 'query { user { email } }',
selection_set_match_type: 'AST_SUBSET'
)
)
).respond(
MockServer::HttpResponse.new(
status_code: 200,
headers: [MockServer::KeyToMultiValue.new(name: 'Content-Type', values: ['application/json'])],
body: '{"data":{"user":{"id":"1","name":"Alice","email":"alice@example.com"}}}'
)
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7"
client := mockserver.New("localhost", 1080)
client.Upsert(mockserver.Expectation{
HttpRequest: &mockserver.HttpRequest{
Method: "POST",
Path: "/graphql",
Body: &mockserver.TypedBody{
Type: "GRAPHQL",
Query: "query { user { email } }",
SelectionSetMatchType: "AST_SUBSET",
},
},
HttpResponse: &mockserver.HttpResponse{
StatusCode: 200,
Headers: map[string][]string{"Content-Type": {"application/json"}},
Body: `{"data":{"user":{"id":"1","name":"Alice","email":"alice@example.com"}}}`,
},
})
using MockServer.Client;
using MockServer.Client.Models;
using var client = new MockServerClient("localhost", 1080);
var body = Body.OfGraphQl("query { user { email } }");
body.SelectionSetMatchType = "AST_SUBSET";
client.Upsert(new Expectation
{
HttpRequest = new HttpRequest { Method = "POST", Path = "/graphql", Body = body },
HttpResponse = new HttpResponse
{
StatusCode = 200,
Headers = new() { ["Content-Type"] = new() { "application/json" } },
Body = "{\"data\":{\"user\":{\"id\":\"1\",\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}"
}
});
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse, Body};
let client = ClientBuilder::new("localhost", 1080).build().unwrap();
// Body::graphql covers only the query — use Body::object for selectionSetMatchType / schema
let body = Body::object(
serde_json::json!({
"type": "GRAPHQL",
"query": "query { user { email } }",
"selectionSetMatchType": "AST_SUBSET"
})
.as_object()
.unwrap()
.clone(),
);
client.when(
HttpRequest::new().method("POST").path("/graphql").body_value(body),
).respond(
HttpResponse::new()
.status_code(200)
.header("Content-Type", "application/json")
.body("{\"data\":{\"user\":{\"id\":\"1\",\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}"),
).unwrap();
<?php
// no typed GRAPHQL body setter — submit the raw expectation JSON via HTTP PUT
$json = '{
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": { "type": "GRAPHQL", "query": "query { user { email } }", "selectionSetMatchType": "AST_SUBSET" }
},
"httpResponse": {
"statusCode": 200,
"headers": { "Content-Type": ["application/json"] },
"body": "{\"data\":{\"user\":{\"id\":\"1\",\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}"
}
}';
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_exec($ch);
curl_close($ch);
curl -s -X PUT http://localhost:1080/mockserver/expectation \
-H "Content-Type: application/json" \
-d '{
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": {
"type": "GRAPHQL",
"query": "query { user { email } }",
"selectionSetMatchType": "AST_SUBSET"
}
},
"httpResponse": {
"statusCode": 200,
"headers": { "Content-Type": ["application/json"] },
"body": "{\"data\":{\"user\":{\"id\":\"1\",\"name\":\"Alice\",\"email\":\"alice@example.com\"}}}"
}
}'
See REST API for full JSON specification
Match by operation name and validate variables with JSON Schema
new MockServerClient("localhost", 1080)
.when(
request()
.withMethod("POST")
.withPath("/graphql")
.withBody(
GraphQLBody.graphQL(
"mutation CreateOrder($input: OrderInput!) { createOrder(input: $input) { id status } }",
"CreateOrder",
"{\"type\":\"object\",\"properties\":{\"input\":{\"type\":\"object\",\"required\":[\"productId\",\"quantity\"]}},\"required\":[\"input\"]}"
)
)
)
.respond(
response()
.withStatusCode(200)
.withHeader("Content-Type", "application/json")
.withBody("{\"data\":{\"createOrder\":{\"id\":\"order-42\",\"status\":\"PENDING\"}}}")
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": {
"type": "GRAPHQL",
"query": "mutation CreateOrder($input: OrderInput!) { createOrder(input: $input) { id status } }",
"operationName": "CreateOrder",
"variablesSchema": "{\"type\":\"object\",\"properties\":{\"input\":{\"type\":\"object\",\"required\":[\"productId\",\"quantity\"]}},\"required\":[\"input\"]}"
}
},
"httpResponse": {
"statusCode": 200,
"headers": { "Content-Type": ["application/json"] },
"body": "{\"data\":{\"createOrder\":{\"id\":\"order-42\",\"status\":\"PENDING\"}}}"
}
}).then(
function () {
console.log("expectation created");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse, GraphQLBody, KeyToMultiValue
client = MockServerClient("localhost", 1080)
client.when(
HttpRequest(
method="POST",
path="/graphql",
body=GraphQLBody(
query="mutation CreateOrder($input: OrderInput!) { createOrder(input: $input) { id status } }",
operation_name="CreateOrder",
variables_schema='{"type":"object","properties":{"input":{"type":"object","required":["productId","quantity"]}},"required":["input"]}',
),
)
).respond(
HttpResponse(
status_code=200,
headers=[KeyToMultiValue(name="Content-Type", values=["application/json"])],
body='{"data":{"createOrder":{"id":"order-42","status":"PENDING"}}}',
)
)
require 'mockserver-client'
client = MockServer::Client.new('localhost', 1080)
client.when(
MockServer::HttpRequest.new(
method: 'POST',
path: '/graphql',
body: MockServer::GraphQLBody.new(
query: 'mutation CreateOrder($input: OrderInput!) { createOrder(input: $input) { id status } }',
operation_name: 'CreateOrder',
variables_schema: '{"type":"object","properties":{"input":{"type":"object","required":["productId","quantity"]}},"required":["input"]}'
)
)
).respond(
MockServer::HttpResponse.new(
status_code: 200,
headers: [MockServer::KeyToMultiValue.new(name: 'Content-Type', values: ['application/json'])],
body: '{"data":{"createOrder":{"id":"order-42","status":"PENDING"}}}'
)
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7"
client := mockserver.New("localhost", 1080)
client.Upsert(mockserver.Expectation{
HttpRequest: &mockserver.HttpRequest{
Method: "POST",
Path: "/graphql",
Body: &mockserver.TypedBody{
Type: "GRAPHQL",
Query: "mutation CreateOrder($input: OrderInput!) { createOrder(input: $input) { id status } }",
OperationName: "CreateOrder",
VariablesSchema: `{"type":"object","properties":{"input":{"type":"object","required":["productId","quantity"]}},"required":["input"]}`,
},
},
HttpResponse: &mockserver.HttpResponse{
StatusCode: 200,
Headers: map[string][]string{"Content-Type": {"application/json"}},
Body: `{"data":{"createOrder":{"id":"order-42","status":"PENDING"}}}`,
},
})
using MockServer.Client;
using MockServer.Client.Models;
using var client = new MockServerClient("localhost", 1080);
var body = Body.OfGraphQl("mutation CreateOrder($input: OrderInput!) { createOrder(input: $input) { id status } }");
body.OperationName = "CreateOrder";
body.VariablesSchema = "{\"type\":\"object\",\"properties\":{\"input\":{\"type\":\"object\",\"required\":[\"productId\",\"quantity\"]}},\"required\":[\"input\"]}";
client.Upsert(new Expectation
{
HttpRequest = new HttpRequest { Method = "POST", Path = "/graphql", Body = body },
HttpResponse = new HttpResponse
{
StatusCode = 200,
Headers = new() { ["Content-Type"] = new() { "application/json" } },
Body = "{\"data\":{\"createOrder\":{\"id\":\"order-42\",\"status\":\"PENDING\"}}}"
}
});
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse, Body};
let client = ClientBuilder::new("localhost", 1080).build().unwrap();
// Body::graphql covers only the query — use Body::object for operationName / variablesSchema
let body = Body::object(
serde_json::json!({
"type": "GRAPHQL",
"query": "mutation CreateOrder($input: OrderInput!) { createOrder(input: $input) { id status } }",
"operationName": "CreateOrder",
"variablesSchema": "{\"type\":\"object\",\"properties\":{\"input\":{\"type\":\"object\",\"required\":[\"productId\",\"quantity\"]}},\"required\":[\"input\"]}"
})
.as_object()
.unwrap()
.clone(),
);
client.when(
HttpRequest::new().method("POST").path("/graphql").body_value(body),
).respond(
HttpResponse::new()
.status_code(200)
.header("Content-Type", "application/json")
.body("{\"data\":{\"createOrder\":{\"id\":\"order-42\",\"status\":\"PENDING\"}}}"),
).unwrap();
<?php
// no typed GRAPHQL body setter — submit the raw expectation JSON via HTTP PUT
$json = '{
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": {
"type": "GRAPHQL",
"query": "mutation CreateOrder($input: OrderInput!) { createOrder(input: $input) { id status } }",
"operationName": "CreateOrder",
"variablesSchema": "{\"type\":\"object\",\"properties\":{\"input\":{\"type\":\"object\",\"required\":[\"productId\",\"quantity\"]}},\"required\":[\"input\"]}"
}
},
"httpResponse": {
"statusCode": 200,
"headers": { "Content-Type": ["application/json"] },
"body": "{\"data\":{\"createOrder\":{\"id\":\"order-42\",\"status\":\"PENDING\"}}}"
}
}';
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_exec($ch);
curl_close($ch);
curl -s -X PUT http://localhost:1080/mockserver/expectation \
-H "Content-Type: application/json" \
-d '{
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": {
"type": "GRAPHQL",
"query": "mutation CreateOrder($input: OrderInput!) { createOrder(input: $input) { id status } }",
"operationName": "CreateOrder",
"variablesSchema": "{\"type\":\"object\",\"properties\":{\"input\":{\"type\":\"object\",\"required\":[\"productId\",\"quantity\"]}},\"required\":[\"input\"]}"
}
},
"httpResponse": {
"statusCode": 200,
"headers": { "Content-Type": ["application/json"] },
"body": "{\"data\":{\"createOrder\":{\"id\":\"order-42\",\"status\":\"PENDING\"}}}"
}
}'
See REST API for full JSON specification
Schema-attached expectation (response synthesized from query)
Provide a schema on the body and omit the response body — MockServer synthesizes a schema-valid response for whatever fields the client requests:
new MockServerClient("localhost", 1080)
.when(
request()
.withMethod("POST")
.withPath("/graphql")
.withBody(
GraphQLBody.graphQL("query { }")
.withSelectionSetMatchType(SelectionSetMatchType.AST_SUBSET)
.withSchema("type Query { user(id: ID!): User } type User { id: ID! name: String email: String }")
)
)
.respond(
response()
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": {
"type": "GRAPHQL",
"query": "query { }",
"selectionSetMatchType": "AST_SUBSET",
"schema": "type Query { user(id: ID!): User } type User { id: ID! name: String email: String }"
}
},
"httpResponse": {}
}).then(
function () {
console.log("expectation created");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse, GraphQLBody
client = MockServerClient("localhost", 1080)
client.when(
HttpRequest(
method="POST",
path="/graphql",
body=GraphQLBody(
query="query { }",
selection_set_match_type="AST_SUBSET",
schema="type Query { user(id: ID!): User } type User { id: ID! name: String email: String }",
),
)
).respond(
HttpResponse()
)
require 'mockserver-client'
client = MockServer::Client.new('localhost', 1080)
# GraphQLBody has no typed schema setter — pass a raw body hash for the schema field
client.when(
MockServer::HttpRequest.new(
method: 'POST',
path: '/graphql',
body: {
'type' => 'GRAPHQL',
'query' => 'query { }',
'selectionSetMatchType' => 'AST_SUBSET',
'schema' => 'type Query { user(id: ID!): User } type User { id: ID! name: String email: String }'
}
)
).respond(
MockServer::HttpResponse.new
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7"
client := mockserver.New("localhost", 1080)
client.Upsert(mockserver.Expectation{
HttpRequest: &mockserver.HttpRequest{
Method: "POST",
Path: "/graphql",
Body: &mockserver.TypedBody{
Type: "GRAPHQL",
Query: "query { }",
SelectionSetMatchType: "AST_SUBSET",
Schema: "type Query { user(id: ID!): User } type User { id: ID! name: String email: String }",
},
},
HttpResponse: &mockserver.HttpResponse{},
})
using MockServer.Client;
using MockServer.Client.Models;
using var client = new MockServerClient("localhost", 1080);
var body = Body.OfGraphQl("query { }");
body.SelectionSetMatchType = "AST_SUBSET";
body.Schema = "type Query { user(id: ID!): User } type User { id: ID! name: String email: String }";
client.Upsert(new Expectation
{
HttpRequest = new HttpRequest { Method = "POST", Path = "/graphql", Body = body },
HttpResponse = new HttpResponse()
});
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse, Body};
let client = ClientBuilder::new("localhost", 1080).build().unwrap();
// Body::graphql covers only the query — use Body::object for selectionSetMatchType / schema
let body = Body::object(
serde_json::json!({
"type": "GRAPHQL",
"query": "query { }",
"selectionSetMatchType": "AST_SUBSET",
"schema": "type Query { user(id: ID!): User } type User { id: ID! name: String email: String }"
})
.as_object()
.unwrap()
.clone(),
);
client.when(
HttpRequest::new().method("POST").path("/graphql").body_value(body),
).respond(
HttpResponse::new(),
).unwrap();
<?php
// no typed GRAPHQL body setter — submit the raw expectation JSON via HTTP PUT
$json = '{
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": {
"type": "GRAPHQL",
"query": "query { }",
"selectionSetMatchType": "AST_SUBSET",
"schema": "type Query { user(id: ID!): User } type User { id: ID! name: String email: String }"
}
},
"httpResponse": {}
}';
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_exec($ch);
curl_close($ch);
curl -s -X PUT http://localhost:1080/mockserver/expectation \
-H "Content-Type: application/json" \
-d '{
"httpRequest": {
"method": "POST",
"path": "/graphql",
"body": {
"type": "GRAPHQL",
"query": "query { }",
"selectionSetMatchType": "AST_SUBSET",
"schema": "type Query { user(id: ID!): User } type User { id: ID! name: String email: String }"
}
},
"httpResponse": {}
}'
See REST API for full JSON specification
GraphQL Error Injection (Chaos)
GraphQL APIs return HTTP 200 even for errors — error details live in an errors array in the response body. Standard HTTP error injection (which changes the status code) does not reproduce this pattern. Use the graphqlErrors chaos profile field to inject a spec-compliant GraphQL error envelope.
See GraphQL Error Injection in the Chaos Testing page for the full reference including graphqlErrorMessage, graphqlErrorCode, graphqlNullifyData, and how to apply it via service-scoped chaos (PUT /mockserver/serviceChaos).
GraphQL Subscriptions
Subscription operations are matched with the same GRAPHQL body type as queries and mutations, but delivery is not automatic: a matched subscription needs an httpWebSocketResponse action that you wire up to push the subscription events back to the client over the WebSocket. The schema import generates the matching expectation; you supply the httpWebSocketResponse with the events you want streamed (and an optional graphqlSubscriptionFilter to deliver only events matching a given subscription query).
A minimal subscription expectation that completes the graphql-ws handshake and then streams two events:
new MockServerClient("localhost", 1080)
.when(
request()
.withMethod("GET")
.withPath("/graphql")
)
.respondWithWebSocket(
webSocketResponse()
.withSubprotocol("graphql-ws")
.withMessage(webSocketMessage("{\"type\":\"connection_ack\"}"))
.withMessage(webSocketMessage("{\"type\":\"next\",\"id\":\"1\",\"payload\":{\"data\":{\"messageAdded\":{\"id\":\"1\",\"text\":\"hello\"}}}}"))
.withMessage(webSocketMessage("{\"type\":\"complete\",\"id\":\"1\"}").withDelay(TimeUnit.MILLISECONDS, 200L))
.withCloseConnection(true)
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
"httpRequest": { "method": "GET", "path": "/graphql" },
"httpWebSocketResponse": {
"subprotocol": "graphql-ws",
"messages": [
{ "text": "{\"type\":\"connection_ack\"}" },
{ "text": "{\"type\":\"next\",\"id\":\"1\",\"payload\":{\"data\":{\"messageAdded\":{\"id\":\"1\",\"text\":\"hello\"}}}}" },
{ "text": "{\"type\":\"complete\",\"id\":\"1\"}", "delay": {"timeUnit": "MILLISECONDS", "value": 200} }
],
"closeConnection": true
}
}).then(
function () {
console.log("expectation created");
},
function (error) {
console.log(error);
}
);
See REST API for full JSON specification
from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpWebSocketResponse, WebSocketMessage, Delay
client = MockServerClient("localhost", 1080)
client.when(
HttpRequest(method="GET", path="/graphql")
).respond_with_websocket(
HttpWebSocketResponse(
subprotocol="graphql-ws",
messages=[
WebSocketMessage(text='{"type":"connection_ack"}'),
WebSocketMessage(text='{"type":"next","id":"1","payload":{"data":{"messageAdded":{"id":"1","text":"hello"}}}}'),
WebSocketMessage(text='{"type":"complete","id":"1"}', delay=Delay(time_unit="MILLISECONDS", value=200)),
],
close_connection=True,
)
)
require 'mockserver-client'
client = MockServer::Client.new('localhost', 1080)
client.when(
MockServer::HttpRequest.new(method: 'GET', path: '/graphql')
).respond_with_websocket(
MockServer::HttpWebSocketResponse.new(
subprotocol: 'graphql-ws',
messages: [
MockServer::WebSocketMessage.new(text: '{"type":"connection_ack"}'),
MockServer::WebSocketMessage.new(text: '{"type":"next","id":"1","payload":{"data":{"messageAdded":{"id":"1","text":"hello"}}}}'),
MockServer::WebSocketMessage.new(text: '{"type":"complete","id":"1"}', delay: MockServer::Delay.new(time_unit: 'MILLISECONDS', value: 200))
],
close_connection: true
)
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7"
client := mockserver.New("localhost", 1080)
client.When(
mockserver.Request().Method("GET").Path("/graphql"),
).RespondWebSocket(
mockserver.WebSocketResponse().
Subprotocol("graphql-ws").
TextMessage(`{"type":"connection_ack"}`).
TextMessage(`{"type":"next","id":"1","payload":{"data":{"messageAdded":{"id":"1","text":"hello"}}}}`).
AddMessage(mockserver.WebSocketMessage{
Text: `{"type":"complete","id":"1"}`,
Delay: &mockserver.Delay{TimeUnit: "MILLISECONDS", Value: 200},
}).
CloseConnection(true),
)
using MockServer.Client;
using MockServer.Client.Models;
using var client = new MockServerClient("localhost", 1080);
client.When(
HttpRequest.Request().WithMethod("GET").WithPath("/graphql")
).RespondWithWebSocket(
HttpWebSocketResponse.Response()
.WithSubprotocol("graphql-ws")
.WithTextMessage("{\"type\":\"connection_ack\"}")
.WithTextMessage("{\"type\":\"next\",\"id\":\"1\",\"payload\":{\"data\":{\"messageAdded\":{\"id\":\"1\",\"text\":\"hello\"}}}}")
.WithMessage(new WebSocketMessage
{
Text = "{\"type\":\"complete\",\"id\":\"1\"}",
Delay = new Delay { TimeUnit = TimeUnit.MILLISECONDS, Value = 200 }
})
.WithCloseConnection(true)
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpWebSocketResponse, WebSocketMessage, Delay};
let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(
HttpRequest::new().method("GET").path("/graphql"),
).respond_with_web_socket(
HttpWebSocketResponse::new()
.subprotocol("graphql-ws")
.message(WebSocketMessage::text("{\"type\":\"connection_ack\"}"))
.message(WebSocketMessage::text("{\"type\":\"next\",\"id\":\"1\",\"payload\":{\"data\":{\"messageAdded\":{\"id\":\"1\",\"text\":\"hello\"}}}}"))
.message(WebSocketMessage::text("{\"type\":\"complete\",\"id\":\"1\"}").delay(Delay::milliseconds(200)))
.close_connection(true),
).unwrap();
<?php
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpWebSocketResponse;
use MockServer\WebSocketMessage;
use MockServer\Delay;
$client = new MockServerClient('localhost', 1080);
$client->when(
HttpRequest::request()->method('GET')->path('/graphql')
)->respondWithWebSocket(
HttpWebSocketResponse::response()
->subprotocol('graphql-ws')
->message(WebSocketMessage::text('{"type":"connection_ack"}'))
->message(WebSocketMessage::text('{"type":"next","id":"1","payload":{"data":{"messageAdded":{"id":"1","text":"hello"}}}}'))
->message(WebSocketMessage::text('{"type":"complete","id":"1"}')->withDelay(Delay::milliseconds(200)))
->closeConnection(true)
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
"httpRequest": { "method": "GET", "path": "/graphql" },
"httpWebSocketResponse": {
"subprotocol": "graphql-ws",
"messages": [
{ "text": "{\"type\":\"connection_ack\"}" },
{ "text": "{\"type\":\"next\",\"id\":\"1\",\"payload\":{\"data\":{\"messageAdded\":{\"id\":\"1\",\"text\":\"hello\"}}}}" },
{ "text": "{\"type\":\"complete\",\"id\":\"1\"}", "delay": {"timeUnit": "MILLISECONDS", "value": 200} }
],
"closeConnection": true
}
}'
See REST API for full JSON specification
See the Creating Expectations page for the full httpWebSocketResponse reference (per-message delays, binary frames, response matchers, and graphqlSubscriptionFilter).
Related Pages
- OpenAPI Import — import an OpenAPI 3.x spec to generate REST mock expectations; the same schema-import pattern as GraphQL
- gRPC Mocking — import a proto descriptor to generate gRPC mock expectations with response synthesis
- AsyncAPI Messaging — mock message-broker interactions from an AsyncAPI spec
- GraphQL Error Injection — inject spec-compliant GraphQL error envelopes via chaos profiles
- Creating Expectations — full reference for the expectation model, body matchers, and response actions