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 executor;
153pub mod graphql_tracing;
154pub mod registry;
155pub mod schema;
156
157pub use executor::{create_graphql_router, start_graphql_server, GraphQLExecutor};
158pub use registry::GraphQLSchemaRegistry;
159pub use schema::GraphQLSchema;
160
161// Re-export tracing utilities
162pub use graphql_tracing::{
163    create_graphql_span, create_resolver_span, record_graphql_error, record_graphql_success,
164    record_resolver_error, record_resolver_success,
165};
166
167/// Start GraphQL server with default configuration
168pub async fn start(port: u16) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
169    start_with_latency(port, None).await
170}
171
172/// Start GraphQL server with latency configuration
173pub async fn start_with_latency(
174    port: u16,
175    latency_profile: Option<LatencyProfile>,
176) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
177    start_graphql_server(port, latency_profile).await
178}
179
180/// Create a GraphQL router with latency support
181pub async fn create_router(
182    latency_profile: Option<LatencyProfile>,
183) -> Result<axum::Router, Box<dyn std::error::Error + Send + Sync>> {
184    create_graphql_router(latency_profile).await
185}
186
187#[cfg(test)]
188mod tests {
189    use super::*;
190
191    #[tokio::test]
192    async fn test_create_router_without_latency() {
193        let result = create_router(None).await;
194        assert!(result.is_ok());
195    }
196
197    #[tokio::test]
198    async fn test_create_router_with_latency() {
199        let latency_profile = LatencyProfile::default();
200        let result = create_router(Some(latency_profile)).await;
201        assert!(result.is_ok());
202    }
203
204    #[tokio::test]
205    async fn test_create_router_with_custom_latency() {
206        let latency_profile = LatencyProfile::with_normal_distribution(50, 10.0);
207        let result = create_router(Some(latency_profile)).await;
208        assert!(result.is_ok());
209    }
210}