| Crates.io | mockforge-graphql |
| lib.rs | mockforge-graphql |
| version | 0.3.31 |
| created_at | 2025-10-16 21:36:10.117515+00 |
| updated_at | 2026-01-04 23:27:07.011678+00 |
| description | GraphQL protocol support for MockForge |
| homepage | https://mockforge.dev |
| repository | https://github.com/SaaSy-Solutions/mockforge |
| max_upload_size | |
| id | 1886802 |
| size | 299,822 |
GraphQL protocol support for MockForge with schema-based query execution.
This crate provides comprehensive GraphQL mocking capabilities, allowing you to define GraphQL schemas and automatically generate realistic resolvers. Perfect for frontend development, API testing, and GraphQL client development.
use mockforge_graphql::start;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Start GraphQL server on port 4000
start(4000).await?;
Ok(())
}
use mockforge_graphql::{GraphQLSchema, GraphQLExecutor, create_graphql_router};
use mockforge_core::LatencyProfile;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Load custom schema
let schema = GraphQLSchema::from_file("schema.graphql").await?;
// Configure latency simulation
let latency = Some(LatencyProfile::fast());
// Create and start server
let router = create_graphql_router(latency).await?;
// ... serve the router
}
Define your GraphQL schema using standard GraphQL SDL (Schema Definition Language):
type Query {
user(id: ID!): User
users(limit: Int = 10, offset: Int = 0): [User!]!
posts(userId: ID): [Post!]!
}
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
deleteUser(id: ID!): Boolean!
}
type Subscription {
userCreated: User!
postAdded(userId: ID): Post!
}
type User {
id: ID!
name: String!
email: String!
avatar: String
posts: [Post!]!
createdAt: DateTime!
updatedAt: DateTime!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
tags: [String!]!
published: Boolean!
createdAt: DateTime!
updatedAt: DateTime!
}
input CreateUserInput {
name: String!
email: String!
avatar: String
}
input UpdateUserInput {
name: String
email: String
avatar: String
}
scalar DateTime
enum UserRole {
ADMIN
MODERATOR
USER
}
MockForge GraphQL automatically generates resolvers with realistic data based on field names and types:
# Get single user
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ user(id: \"123\") { id name email avatar } }"}'
# Get users with pagination
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ users(limit: 5) { id name email posts { title } } }"}'
# Create user
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "mutation CreateUser($input: CreateUserInput!) { createUser(input: $input) { id name email } }",
"variables": {
"input": {
"name": "Alice Johnson",
"email": "alice@example.com",
"avatar": "https://example.com/avatar.jpg"
}
}
}'
# Update user
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "mutation UpdateUser($id: ID!, $input: UpdateUserInput!) { updateUser(id: $id, input: $input) { id name email } }",
"variables": {
"id": "123",
"input": { "name": "Alice Smith" }
}
}'
Access the interactive GraphQL Playground at http://localhost:4000/playground for:
Simulate realistic network conditions:
use mockforge_graphql::start_with_latency;
use mockforge_core::LatencyProfile;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Simulate slow API
let latency = LatencyProfile::slow(); // 300-800ms
start_with_latency(4000, Some(latency)).await?;
Ok(())
}
use mockforge_core::LatencyProfile;
// Fixed delay
let fixed_latency = LatencyProfile::with_fixed_delay(500); // 500ms
// Normal distribution
let normal_latency = LatencyProfile::with_normal_distribution(200, 50.0); // mean 200ms, std dev 50ms
// Custom range
let range_latency = LatencyProfile::with_range(100, 1000); // 100-1000ms
Simulate GraphQL errors:
use mockforge_graphql::GraphQLExecutor;
// Configure error injection
let executor = GraphQLExecutor::new(schema)
.with_error_rate(0.1) // 10% error rate
.with_error_types(vec![
"USER_NOT_FOUND",
"VALIDATION_ERROR",
"INTERNAL_SERVER_ERROR"
]);
Enable distributed tracing:
use mockforge_graphql::graphql_tracing::{create_graphql_span, record_graphql_success};
// Create spans for monitoring
let span = create_graphql_span("query", "GetUser");
// Execute query...
// Record success
record_graphql_success(&span, 150); // 150ms duration
Manage multiple GraphQL schemas:
use mockforge_graphql::GraphQLSchemaRegistry;
// Create registry
let registry = GraphQLSchemaRegistry::new();
// Register schemas
registry.register_schema("v1", schema_v1).await?;
registry.register_schema("v2", schema_v2).await?;
// Switch between versions
registry.set_active_schema("v2").await?;
MockForge GraphQL integrates seamlessly with the broader MockForge ecosystem:
use mockforge_graphql::GraphQLExecutor;
use mockforge_core::LatencyProfile;
// Configure executor
let executor = GraphQLExecutor::new(schema)
.with_latency_profile(LatencyProfile::normal())
.with_max_query_depth(10)
.with_max_query_complexity(1000)
.with_introspection_enabled(true)
.with_playground_enabled(true);
# Server configuration
export GRAPHQL_PORT=4000
export GRAPHQL_ENABLE_PLAYGROUND=true
export GRAPHQL_ENABLE_INTROSPECTION=true
# Latency simulation
export GRAPHQL_LATENCY_PROFILE=normal
export GRAPHQL_LATENCY_FIXED_MS=200
# Error injection
export GRAPHQL_ERROR_RATE=0.05
export GRAPHQL_ERROR_TYPES="VALIDATION_ERROR,INTERNAL_ERROR"
Use MockForge GraphQL for comprehensive testing:
use mockforge_graphql::GraphQLExecutor;
#[tokio::test]
async fn test_user_query() {
let schema = GraphQLSchema::from_string(SCHEMA).await.unwrap();
let executor = GraphQLExecutor::new(schema);
let query = r#"
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
"#;
let variables = serde_json::json!({ "id": "123" });
let result = executor.execute(query, Some(variables)).await.unwrap();
assert!(result.errors.is_empty());
assert!(result.data.is_object());
}
use reqwest::Client;
#[tokio::test]
async fn test_graphql_endpoint() {
let client = Client::new();
let query = serde_json::json!({
"query": "{ users { id name } }",
"variables": null
});
let response = client
.post("http://localhost:4000/graphql")
.json(&query)
.send()
.await
.unwrap();
assert_eq!(response.status(), 200);
let result: serde_json::Value = response.json().await.unwrap();
assert!(result.get("data").is_some());
}
use axum::{routing::get, Router};
use mockforge_graphql::{create_graphql_router, GraphQLSchema};
use mockforge_core::LatencyProfile;
use std::net::SocketAddr;
use tower_http::cors::CorsLayer;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Load schema
let schema = GraphQLSchema::from_file("schema.graphql").await?;
// Configure latency
let latency = Some(LatencyProfile::normal());
// Create GraphQL router
let graphql_router = create_graphql_router(latency).await?;
// Add CORS and other middleware
let app = Router::new()
.merge(graphql_router)
.layer(CorsLayer::permissive());
// Start server
let addr = SocketAddr::from(([127, 0, 0, 1], 4000));
println!("🚀 GraphQL server running at http://{}", addr);
println!("📖 GraphQL Playground at http://{}/playground", addr);
axum::serve(tokio::net::TcpListener::bind(addr).await?, app).await?;
Ok(())
}
use async_graphql::*;
use mockforge_graphql::GraphQLSchema;
// Define custom resolvers
struct Query;
#[Object]
impl Query {
async fn custom_user(&self, ctx: &Context<'_>, id: ID) -> Result<User> {
// Custom logic here
Ok(User {
id,
name: "Custom User".to_string(),
email: "custom@example.com".to_string(),
})
}
}
// Register custom resolvers
let schema = Schema::build(Query, EmptyMutation, EmptySubscription)
.data(custom_data)
.finish();
Schema validation errors:
Query execution errors:
Performance issues:
mockforge-core: Core mocking functionalitymockforge-data: Synthetic data generationasync-graphql: Underlying GraphQL implementationLicensed under MIT OR Apache-2.0