mockforge_graphql/
lib.rs

1//! # MockForge GraphQL
2//!
3//! GraphQL mocking library for MockForge with schema-based query execution.
4//!
5//! This crate provides GraphQL mocking capabilities including:
6//!
7//! - **Schema-Based Mocking**: Define GraphQL schemas and automatically generate resolvers
8//! - **Query & Mutation Support**: Handle queries, mutations, and subscriptions
9//! - **Type System**: Full GraphQL type system support (scalars, objects, interfaces, unions)
10//! - **Introspection**: Built-in introspection queries for tooling
11//! - **Playground Integration**: GraphQL Playground UI for interactive testing
12//!
13//! ## Overview
14//!
15//! MockForge GraphQL allows you to define GraphQL schemas and automatically mock
16//! resolvers with realistic data. Perfect for frontend development and integration testing.
17//!
18//! ## Quick Start
19//!
20//! ### Basic GraphQL Server
21//!
22//! ```rust,no_run
23//! use mockforge_graphql::start;
24//!
25//! #[tokio::main]
26//! async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
27//!     // Start GraphQL server on port 4000
28//!     start(4000).await?;
29//!     Ok(())
30//! }
31//! ```
32//!
33//! ### With Custom Schema
34//!
35//! ```rust,no_run
36//! use mockforge_graphql::{create_graphql_router, GraphQLSchema};
37//! use mockforge_core::LatencyProfile;
38//!
39//! # async fn example() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
40//! let schema = GraphQLSchema::generate_basic_schema();
41//! assert!(schema.schema().sdl().contains("type Query"));
42//! let latency = Some(LatencyProfile::with_normal_distribution(80, 20.0));
43//! let _router = create_graphql_router(latency).await?;
44//! # Ok(())
45//! # }
46//! ```
47//!
48//! ## GraphQL Schema Example
49//!
50//! Define your GraphQL schema:
51//!
52//! ```graphql
53//! type Query {
54//!   user(id: ID!): User
55//!   users(limit: Int = 10): [User!]!
56//! }
57//!
58//! type Mutation {
59//!   createUser(input: CreateUserInput!): User!
60//!   updateUser(id: ID!, input: UpdateUserInput!): User!
61//! }
62//!
63//! type User {
64//!   id: ID!
65//!   name: String!
66//!   email: String!
67//!   posts: [Post!]!
68//! }
69//!
70//! type Post {
71//!   id: ID!
72//!   title: String!
73//!   content: String!
74//!   author: User!
75//! }
76//!
77//! input CreateUserInput {
78//!   name: String!
79//!   email: String!
80//! }
81//! ```
82//!
83//! MockForge automatically generates resolvers with realistic data:
84//!
85//! ```bash
86//! # Query
87//! curl -X POST http://localhost:4000/graphql \
88//!   -H "Content-Type: application/json" \
89//!   -d '{"query": "{ user(id: \"123\") { id name email } }"}'
90//!
91//! # Mutation
92//! curl -X POST http://localhost:4000/graphql \
93//!   -H "Content-Type: application/json" \
94//!   -d '{"query": "mutation { createUser(input: {name: \"Alice\", email: \"alice@example.com\"}) { id } }"}'
95//! ```
96//!
97//! ## GraphQL Playground
98//!
99//! Access the interactive GraphQL Playground at:
100//! ```text
101//! http://localhost:4000/playground
102//! ```
103//!
104//! The Playground provides:
105//! - Schema explorer
106//! - Query editor with auto-complete
107//! - Response viewer
108//! - Request history
109//!
110//! ## Features
111//!
112//! ### Automatic Resolver Generation
113//! - Generates realistic data based on field names and types
114//! - Maintains referential integrity between related types
115//! - Supports nested queries and relationships
116//!
117//! ### Latency Simulation
118//! - Simulate network delays for realistic testing
119//! - Per-resolver latency configuration
120//! - Random or fixed latency profiles
121//!
122//! ### Error Injection
123//! - Simulate GraphQL errors and partial responses
124//! - Configure error rates per resolver
125//! - Test error handling in client applications
126//!
127//! ## Key Modules
128//!
129//! - [`executor`]: GraphQL query execution engine
130//! - [`schema`]: Schema parsing and validation
131//! - [`registry`]: Type and resolver registry
132//! - [`graphql_tracing`]: Distributed tracing integration
133//!
134//! ## Examples
135//!
136//! See the [examples directory](https://github.com/SaaSy-Solutions/mockforge/tree/main/examples)
137//! for complete working examples.
138//!
139//! ## Related Crates
140//!
141//! - [`mockforge-core`](https://docs.rs/mockforge-core): Core mocking functionality
142//! - [`mockforge-data`](https://docs.rs/mockforge-data): Synthetic data generation
143//!
144//! ## Documentation
145//!
146//! - [MockForge Book](https://docs.mockforge.dev/)
147//! - [GraphQL Mocking Guide](https://docs.mockforge.dev/user-guide/graphql-mocking.html)
148//! - [API Reference](https://docs.rs/mockforge-graphql)
149
150use mockforge_core::LatencyProfile;
151
152pub mod cache;
153pub mod executor;
154pub mod graphql_tracing;
155pub mod handlers;
156pub mod registry;
157pub mod resolvers;
158pub mod schema;
159pub mod schema_watcher;
160pub mod subscriptions;
161
162pub use cache::{CacheConfig, CacheKey, CacheMiddleware, CacheStats, ResponseCache};
163pub use executor::{create_graphql_router, start_graphql_server, GraphQLExecutor};
164pub use handlers::{
165    GraphQLContext, GraphQLHandler, HandlerRegistry, HandlerResult, OperationType, VariableMatcher,
166    VariablePattern,
167};
168pub use registry::GraphQLSchemaRegistry;
169pub use schema::GraphQLSchema;
170pub use schema_watcher::SchemaWatcher;
171pub use subscriptions::{
172    MockSubscriptionHandler, SubscriptionEvent, SubscriptionHandler, SubscriptionId,
173    SubscriptionManager, SubscriptionMetadata, Topic,
174};
175
176// Re-export tracing utilities
177pub use graphql_tracing::{
178    create_graphql_span, create_resolver_span, record_graphql_error, record_graphql_success,
179    record_resolver_error, record_resolver_success,
180};
181
182/// Start GraphQL server with default configuration
183pub async fn start(port: u16) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
184    start_with_latency(port, None).await
185}
186
187/// Start GraphQL server with latency configuration
188pub async fn start_with_latency(
189    port: u16,
190    latency_profile: Option<LatencyProfile>,
191) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
192    start_graphql_server(port, latency_profile).await
193}
194
195/// Create a GraphQL router with latency support
196pub async fn create_router(
197    latency_profile: Option<LatencyProfile>,
198) -> Result<axum::Router, Box<dyn std::error::Error + Send + Sync>> {
199    create_graphql_router(latency_profile).await
200}
201
202#[cfg(test)]
203mod tests {
204    use super::*;
205
206    #[tokio::test]
207    async fn test_create_router_without_latency() {
208        let result = create_router(None).await;
209        assert!(result.is_ok());
210    }
211
212    #[tokio::test]
213    async fn test_create_router_with_latency() {
214        let latency_profile = LatencyProfile::default();
215        let result = create_router(Some(latency_profile)).await;
216        assert!(result.is_ok());
217    }
218
219    #[tokio::test]
220    async fn test_create_router_with_custom_latency() {
221        let latency_profile = LatencyProfile::with_normal_distribution(50, 10.0);
222        let result = create_router(Some(latency_profile)).await;
223        assert!(result.is_ok());
224    }
225}