grafbase_sdk_mock/
lib.rs

1//! Provides a dynamic GraphQL schema and subgraph implementation that can be built and executed at runtime.
2//!
3//! This crate allows creating GraphQL schemas dynamically from SDL (Schema Definition Language) strings
4//! and executing queries against them. It also provides functionality for running mock GraphQL servers
5//! using these dynamic schemas.
6
7#![deny(missing_docs)]
8
9mod builder;
10mod entity_resolver;
11mod resolver;
12mod server;
13
14use std::{
15    path::{Path, PathBuf},
16    sync::Arc,
17};
18
19pub use builder::DynamicSchemaBuilder;
20pub use server::MockGraphQlServer;
21
22/// A dynamic GraphQL schema that can be built and executed at runtime.
23#[derive(Debug, Clone)]
24pub struct DynamicSchema {
25    schema: async_graphql::dynamic::Schema,
26    sdl: String,
27}
28
29impl DynamicSchema {
30    /// Creates a builder for constructing a new dynamic subgraph schema from SDL.
31    ///
32    /// # Arguments
33    ///
34    /// * `sdl` - GraphQL schema definition language string to build from
35    pub fn builder(sdl: impl AsRef<str>) -> DynamicSchemaBuilder {
36        DynamicSchemaBuilder::new(sdl.as_ref())
37    }
38
39    /// Executes a GraphQL request against this schema.
40    pub async fn execute(&self, request: async_graphql::Request) -> async_graphql::Response {
41        self.schema.execute(request).await
42    }
43
44    /// Returns the SDL (Schema Definition Language) string for this schema.
45    pub fn sdl(&self) -> &str {
46        &self.sdl
47    }
48}
49
50/// A dynamic subgraph implementation that can be started as a mock GraphQL server.
51#[derive(Debug, Clone)]
52pub struct DynamicSubgraph {
53    schema: DynamicSchema,
54    name: String,
55}
56
57impl DynamicSubgraph {
58    /// Starts this subgraph as a mock GraphQL server.
59    ///
60    /// Returns a handle to the running server that can be used to stop it.
61    pub async fn start(self) -> MockGraphQlServer {
62        MockGraphQlServer::new(self.name, Arc::new(self.schema)).await
63    }
64}
65
66/// A subgraph that only contains extension definitions. We do not spawn a GraphQL server for this subgraph.
67#[derive(Debug)]
68pub struct ExtensionOnlySubgraph {
69    schema: DynamicSchema,
70    name: String,
71    extension_path: PathBuf,
72}
73
74impl ExtensionOnlySubgraph {
75    /// Returns the SDL (Schema Definition Language) string for this schema
76    pub fn sdl(&self) -> &str {
77        self.schema.sdl()
78    }
79
80    /// Returns the name of this subgraph
81    pub fn name(&self) -> &str {
82        &self.name
83    }
84
85    /// Returns the path to the extension definitions for this subgraph
86    pub fn extension_path(&self) -> &Path {
87        &self.extension_path
88    }
89}
90
91/// A mock subgraph that can either be a full dynamic GraphQL service or just extension definitions.
92#[derive(Debug)]
93pub enum MockSubgraph {
94    /// A full dynamic subgraph that can be started as a GraphQL server
95    Dynamic(DynamicSubgraph),
96    /// A subgraph that only contains extension definitions and is not started as a server
97    ExtensionOnly(ExtensionOnlySubgraph),
98}
99
100impl From<DynamicSubgraph> for MockSubgraph {
101    fn from(subgraph: DynamicSubgraph) -> Self {
102        MockSubgraph::Dynamic(subgraph)
103    }
104}
105
106impl From<ExtensionOnlySubgraph> for MockSubgraph {
107    fn from(subgraph: ExtensionOnlySubgraph) -> Self {
108        MockSubgraph::ExtensionOnly(subgraph)
109    }
110}