grafbase_sdk/extension/resolver.rs
1use crate::{
2 component::AnyExtension,
3 types::{Error, FieldDefinitionDirective, FieldInputs, FieldOutput},
4 Headers,
5};
6
7use super::Extension;
8
9/// A trait that extends `Extension` and provides functionality for resolving fields.
10///
11/// Implementors of this trait are expected to provide a method to resolve field values based on
12/// the given context, directive, and inputs. This is typically used in scenarios where field
13/// resolution logic needs to be encapsulated within a resolver object, allowing for modular
14/// and reusable code design.
15pub trait Resolver: Extension {
16 /// Resolves a field value based on the given context, directive, definition, and inputs.
17 ///
18 /// # Arguments
19 ///
20 /// * `headers` - The subgraph headers associated with this field resolution
21 /// * `subgraph_name` - The name of the subgraph associated with this field resolution
22 /// * `directive` - The directive associated with this field resolution
23 /// * `definition` - The field definition containing metadata
24 /// * `inputs` - The input values provided for this field
25 ///
26 /// # Returns
27 ///
28 /// Returns a `Result` containing either the resolved `FieldOutput` value or an `Error`
29 fn resolve_field(
30 &mut self,
31 headers: Headers,
32 subgraph_name: &str,
33 directive: FieldDefinitionDirective<'_>,
34 inputs: FieldInputs,
35 ) -> Result<FieldOutput, Error>;
36
37 /// Resolves a subscription field by setting up a subscription handler.
38 ///
39 /// # Arguments
40 ///
41 /// * `headers` - The subgraph headers associated with this field resolution
42 /// * `directive` - The directive associated with this subscription field
43 /// * `definition` - The field definition containing metadata about the subscription
44 ///
45 /// # Returns
46 ///
47 /// Returns a `Result` containing either a boxed `Subscriber` implementation or an `Error`
48 fn resolve_subscription(
49 &mut self,
50 headers: Headers,
51 subgraph_name: &str,
52 directive: FieldDefinitionDirective<'_>,
53 ) -> Result<Box<dyn Subscription>, Error>;
54}
55
56/// A trait for consuming field outputs from streams.
57///
58/// This trait provides an abstraction over different implementations
59/// of subscriptions to field output streams. Implementors should handle
60/// the details of their specific transport mechanism while providing a
61/// consistent interface for consumers.
62pub trait Subscription {
63 /// Retrieves the next field output from the subscription.
64 ///
65 /// Returns:
66 /// - `Ok(Some(FieldOutput))` if a field output was available
67 /// - `Ok(None)` if the subscription has ended normally
68 /// - `Err(Error)` if an error occurred while retrieving the next field output
69 fn next(&mut self) -> Result<Option<FieldOutput>, Error>;
70}
71
72#[doc(hidden)]
73pub fn register<T: Resolver>() {
74 pub(super) struct Proxy<T: Resolver>(T);
75
76 impl<T: Resolver> AnyExtension for Proxy<T> {
77 fn resolve_field(
78 &mut self,
79 headers: Headers,
80 subgraph_name: &str,
81 directive: FieldDefinitionDirective<'_>,
82 inputs: FieldInputs,
83 ) -> Result<FieldOutput, Error> {
84 Resolver::resolve_field(&mut self.0, headers, subgraph_name, directive, inputs)
85 }
86 fn resolve_subscription(
87 &mut self,
88 headers: Headers,
89 subgraph_name: &str,
90 directive: FieldDefinitionDirective<'_>,
91 ) -> Result<Box<dyn Subscription>, Error> {
92 Resolver::resolve_subscription(&mut self.0, headers, subgraph_name, directive)
93 }
94 }
95 crate::component::register_extension(Box::new(|schema_directives, config| {
96 <T as Extension>::new(schema_directives, config)
97 .map(|extension| Box::new(Proxy(extension)) as Box<dyn AnyExtension>)
98 }))
99}