What you’ll build
A GraphQL API with:- Type-safe schema definitions
- Query resolvers for fetching data
- Mutation resolvers for creating data
- Dynamic response generation
- Multiple entity types (users, posts)
name: GraphQL API
version: "1.0"
description: A GraphQL API for blog posts and users
server:
port: 9006
base_path: /graphql
schema: |
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
published: Boolean!
}
type Query {
user(id: ID!): User
users: [User!]!
post(id: ID!): Post
posts: [Post!]!
}
type Mutation {
createUser(name: String!, email: String!): User!
createPost(title: String!, content: String!, authorId: ID!): Post!
}
fixtures:
users:
- id: "1"
name: "Alice Johnson"
email: "[email protected]"
- id: "2"
name: "Bob Smith"
email: "[email protected]"
posts:
- id: "1"
title: "Getting Started with GraphQL"
content: "GraphQL is a query language for APIs..."
authorId: "1"
published: true
- id: "2"
title: "Advanced GraphQL Patterns"
content: "Learn about fragments, directives..."
authorId: "1"
published: false
endpoints:
- method: POST
path: /graphql
description: GraphQL endpoint
responses:
200:
content_type: application/json
body: |
{
"data": {
"users": [
{{#each fixtures.users}}
{
"id": "{{id}}",
"name": "{{name}}",
"email": "{{email}}",
"posts": [
{{#each (filter ../fixtures.posts authorId=id)}}
{
"id": "{{id}}",
"title": "{{title}}",
"content": "{{content}}",
"published": {{published}}
}{{#unless @last}},{{/unless}}
{{/each}}
]
}{{#unless @last}},{{/unless}}
{{/each}}
]
}
}
- method: POST
path: /graphql
description: Create user mutation
request_body:
content_type: application/json
responses:
200:
condition: "{{contains request.body.query 'createUser'}}"
content_type: application/json
body: |
{
"data": {
"createUser": {
"id": "{{faker 'datatype.uuid'}}",
"name": "{{request.body.variables.name}}",
"email": "{{request.body.variables.email}}",
"posts": []
}
}
}
curl -X POST http://localhost:9006/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "{ users { id name email posts { id title published } } }"
}'
{
"data": {
"users": [
{
"id": "1",
"name": "Alice Johnson",
"email": "[email protected]",
"posts": [
{
"id": "1",
"title": "Getting Started with GraphQL",
"published": true
},
{
"id": "2",
"title": "Advanced GraphQL Patterns",
"published": false
}
]
},
{
"id": "2",
"name": "Bob Smith",
"email": "[email protected]",
"posts": []
}
]
}
}
curl -X POST http://localhost:9006/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "query GetUser($id: ID!) { user(id: $id) { id name email } }",
"variables": { "id": "1" }
}'
{
"data": {
"user": {
"id": "1",
"name": "Alice Johnson",
"email": "[email protected]"
}
}
}
curl -X POST http://localhost:9006/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "mutation CreateUser($name: String!, $email: String!) { createUser(name: $name, email: $email) { id name email } }",
"variables": {
"name": "Charlie Davis",
"email": "[email protected]"
}
}'
{
"data": {
"createUser": {
"id": "a3f2c8d1-4e5b-6c7d-8e9f-0a1b2c3d4e5f",
"name": "Charlie Davis",
"email": "[email protected]",
"posts": []
}
}
}
Key features demonstrated
Schema definition
Define your GraphQL schema using SDL (Schema Definition Language):! indicates non-nullable fields.
Fixtures for GraphQL data
Define test data that matches your schema:Query resolvers
Map GraphQL queries to response templates:Mutation resolvers
Handle create/update/delete operations:Use
{{contains request.body.query 'mutationName'}} to detect which mutation is being called.Variables support
Access GraphQL variables in your templates:Nested relationships
Simulate relationships between types:Advanced patterns
Error handling
Return GraphQL errors for invalid requests:Pagination
Implement cursor-based pagination:Fragments
Support GraphQL fragments:Directives
Handle@include and @skip directives:
Generate from schema
Create a new GraphQL service from scratch:- Basic schema structure
- Sample types and queries
- Mutation examples
- Ready-to-customize fixtures
Testing with GraphQL clients
Apollo Client (React)
URQL (React/Vue/Svelte)
Relay (React)
Best practices
Type safety
Use code generation for type-safe clients:Introspection
Enable GraphQL introspection for development:Error codes
Use consistent error codes in extensions:Next steps
- Add subscriptions for real-time updates
- Implement authentication with context
- Create complex nested queries
- Set up contract testing against a real GraphQL API
- Export schema for documentation