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}