Struct warpgrapher::engine::resolvers::ResolverFacade
source · [−]pub struct ResolverFacade<'a, RequestCtx> where
RequestCtx: RequestContext, { /* private fields */ }
Expand description
Provides a simplified interface to primitive operations such as Node creation, Rel creation,
resolution of both scalar and complex types. The ResolverFacade
is the primary mechanism
trough which a custom resolver interacts with the rest of the framework.
Implementations
sourceimpl<'a, RequestCtx> ResolverFacade<'a, RequestCtx> where
RequestCtx: RequestContext,
impl<'a, RequestCtx> ResolverFacade<'a, RequestCtx> where
RequestCtx: RequestContext,
sourcepub fn input<T: DeserializeOwned>(&self) -> Result<T, Error>
pub fn input<T: DeserializeOwned>(&self) -> Result<T, Error>
Returns the resolver input deserialized into a structure of type T that
implements the serde Deserialize
trait.
Errors
Returns an [Error]
variant InputItemNotFound
if no input field was passed
to the query, TypeConversionFailed
if unable to convert a Value
to a serde_json Value, and JsonDeserializationFailed
if unable to parse the
input data into a struct of type T.
sourcepub fn metadata(&self) -> &HashMap<String, String>
pub fn metadata(&self) -> &HashMap<String, String>
Returns the execution metadata that was passed to the engine. If no metadata was
passed to the engine’s execute
method, an empty HashMap is returned.
Examples
fn custom_resolve(facade: ResolverFacade<()>) -> ExecutionResult {
let execution_metadata = facade.metadata();
// use metadata
facade.resolve_null()
}
sourcepub fn args(&self) -> &Arguments<'_>
pub fn args(&self) -> &Arguments<'_>
Returns the arguments provided to the resolver in the GraphQL query
Examples
fn custom_resolve(facade: ResolverFacade<()>) -> ExecutionResult {
let args = facade.args();
// use arguments
facade.resolve_null()
}
sourcepub fn node(
&self,
typename: &str,
props: HashMap<String, Value>
) -> Node<RequestCtx>
pub fn node(
&self,
typename: &str,
props: HashMap<String, Value>
) -> Node<RequestCtx>
Creates a Node
, of a given type, with a set of properites
Examples
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
let typename = "User";
let mut props = HashMap::new();
props.insert("role".to_string(), Value::String("Admin".to_string()));
let n = facade.node(typename, props);
facade.resolve_node(&n).await
})
}
sourcepub async fn read_nodes(
rf: &ResolverFacade<'_, RequestCtx>,
type_name: &str,
input: impl TryInto<Value>,
partition_key_opt: Option<&Value>,
transaction: &'a mut <<<RequestCtx as RequestContext>::DBEndpointType as DatabaseEndpoint>::PoolType as DatabasePool>::TransactionType
) -> Result<Vec<Node<RequestCtx>>, Error>
pub async fn read_nodes(
rf: &ResolverFacade<'_, RequestCtx>,
type_name: &str,
input: impl TryInto<Value>,
partition_key_opt: Option<&Value>,
transaction: &'a mut <<<RequestCtx as RequestContext>::DBEndpointType as DatabaseEndpoint>::PoolType as DatabasePool>::TransactionType
) -> Result<Vec<Node<RequestCtx>>, Error>
Provides an abstracted database node read operation using warpgrapher inputs. This is the recommended way to read data in a database-agnostic way that ensures the event handlers are portable across different databases.
Arguments
type_name
- String reference represing name of node type (ex: “User”).input
- OptionalValue
describing which node to match. Same input structure passed to a READ crud operation (<Type>QueryInput
).partition_key_opt
- OptionalValue
describing the partition key if the underlying database supports it.
Examples
fn custom_resolve(mut facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
let mut transaction = facade.executor().context().pool().transaction().await?;
transaction.begin().await?;
let result = ResolverFacade::read_nodes(&facade, "User", json!({"name": "alice"}),
None, &mut transaction).await?;
let alice = result.first().unwrap();
transaction.commit().await?;
std::mem::drop(transaction);
facade.resolve_node(&alice).await
})
}
sourcepub async fn read_rels(
&self,
src_node_label: &str,
rel_label: &str,
input: impl TryInto<Value>,
partition_key_opt: Option<&Value>,
transaction: &'a mut <<<RequestCtx as RequestContext>::DBEndpointType as DatabaseEndpoint>::PoolType as DatabasePool>::TransactionType
) -> Result<Vec<Rel<RequestCtx>>, Error>
pub async fn read_rels(
&self,
src_node_label: &str,
rel_label: &str,
input: impl TryInto<Value>,
partition_key_opt: Option<&Value>,
transaction: &'a mut <<<RequestCtx as RequestContext>::DBEndpointType as DatabaseEndpoint>::PoolType as DatabasePool>::TransactionType
) -> Result<Vec<Rel<RequestCtx>>, Error>
Provides an abstracted database rel read operation using warpgrapher inputs. This is the recommended way to read relationships in a database-agnostic way that ensures the event handlers are portable across different databases.
Arguments
src_node_label
- String reference represing name of node type (ex: “User”).rel_label
- String reference representing the name of the relationship (ex: “teams”).input
-Value
describing the relationship query input.partition_key_opt
- OptionalValue
describing the partition key if the underlying database supports it.
Examples
fn before_user_read(value: Value, mut ef: EventFacade<()>) -> BoxFuture<Result<Value, Error>> {
Box::pin(async move {
let rels: Vec<Rel<()>> = ef.read_rels(
"User",
"teams",
json!({
"src": {"name": {"EQ": "alice"}}
}),
None).await?;
Ok(value)
})
}
sourcepub async fn create_node(
rf: &'a ResolverFacade<'_, RequestCtx>,
type_name: &str,
input: impl TryInto<Value>,
partition_key_opt: Option<&Value>,
transaction: &'a mut <<<RequestCtx as RequestContext>::DBEndpointType as DatabaseEndpoint>::PoolType as DatabasePool>::TransactionType
) -> Result<Node<RequestCtx>, Error>
pub async fn create_node(
rf: &'a ResolverFacade<'_, RequestCtx>,
type_name: &str,
input: impl TryInto<Value>,
partition_key_opt: Option<&Value>,
transaction: &'a mut <<<RequestCtx as RequestContext>::DBEndpointType as DatabaseEndpoint>::PoolType as DatabasePool>::TransactionType
) -> Result<Node<RequestCtx>, Error>
Provides an abstracted database node create operation using warpgrapher inputs. This is the recommended way to read data in a database-agnostic way that ensures the event handlers are portable across different databases.
Arguments
type_name
- String reference represing name of node type (ex: “User”).input
- OptionalValue
describing which node to match. Same input structure passed to a READ crud operation (<Type>QueryInput
).partition_key_opt
- OptionalValue
describing the partition key if the underlying database supports it.
Examples
fn custom_resolve(mut facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
let mut transaction = facade.executor().context().pool().transaction().await?;
transaction.begin().await?;
let result = ResolverFacade::create_node(&facade, "User", json!({"name": "alice"}), None, &mut transaction).await;
if result.is_ok() {
transaction.commit().await?;
} else {
transaction.rollback().await?;
}
let alice = result?;
std::mem::drop(transaction);
facade.resolve_node(&alice).await
})
}
sourcepub async fn update_node(
rf: &ResolverFacade<'_, RequestCtx>,
type_name: &str,
input: impl TryInto<Value>,
partition_key_opt: Option<&Value>,
transaction: &'a mut <<<RequestCtx as RequestContext>::DBEndpointType as DatabaseEndpoint>::PoolType as DatabasePool>::TransactionType
) -> Result<Vec<Node<RequestCtx>>, Error>
pub async fn update_node(
rf: &ResolverFacade<'_, RequestCtx>,
type_name: &str,
input: impl TryInto<Value>,
partition_key_opt: Option<&Value>,
transaction: &'a mut <<<RequestCtx as RequestContext>::DBEndpointType as DatabaseEndpoint>::PoolType as DatabasePool>::TransactionType
) -> Result<Vec<Node<RequestCtx>>, Error>
Provides an abstracted database node update operation using warpgrapher inputs. This is the recommended way to read data in a database-agnostic way that ensures the event handlers are portable across different databases.
Arguments
type_name
- String reference represing name of node type (ex: “User”).input
- OptionalValue
describing which node to match. Same input structure passed to a READ crud operation (<Type>QueryInput
).partition_key_opt
- OptionalValue
describing the partition key if the underlying database supports it.
Examples
fn custom_resolve(mut facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
let mut transaction = facade.executor().context().pool().transaction().await?;
transaction.begin().await?;
let result = ResolverFacade::update_node(
&facade,
"User",
json!({
"MATCH": {
"name": {
"EQ":"alice"
}
},
"SET": {
"age": 20
}
}),
None,
&mut transaction
).await?;
transaction.commit().await?;
std::mem::drop(transaction);
let alice = result.first().unwrap();
facade.resolve_node(&alice).await
})
}
sourcepub async fn delete_node(
rf: &ResolverFacade<'_, RequestCtx>,
type_name: &str,
input: impl TryInto<Value>,
partition_key_opt: Option<&Value>,
transaction: &'a mut <<<RequestCtx as RequestContext>::DBEndpointType as DatabaseEndpoint>::PoolType as DatabasePool>::TransactionType
) -> Result<Vec<Node<RequestCtx>>, Error>
pub async fn delete_node(
rf: &ResolverFacade<'_, RequestCtx>,
type_name: &str,
input: impl TryInto<Value>,
partition_key_opt: Option<&Value>,
transaction: &'a mut <<<RequestCtx as RequestContext>::DBEndpointType as DatabaseEndpoint>::PoolType as DatabasePool>::TransactionType
) -> Result<Vec<Node<RequestCtx>>, Error>
Provides an abstracted database node delete operation using warpgrapher inputs. This is the recommended way to read data in a database-agnostic way that ensures the event handlers are portable across different databases.
Arguments
type_name
- String reference represing name of node type (ex: “User”).input
- OptionalValue
describing which node to match. Same input structure passed to a READ crud operation (<Type>QueryInput
).partition_key_opt
- OptionalValue
describing the partition key if the underlying database supports it.
Examples
fn custom_resolve(mut facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
let mut transaction = facade.executor().context().pool().transaction().await?;
transaction.begin().await?;
ResolverFacade::delete_node(
&facade,
"User",
json!({
"MATCH": {
"name": {
"EQ":"alice"
}
}
}),
None,
&mut transaction
).await?;
transaction.commit().await?;
std::mem::drop(transaction);
facade.resolve_null()
})
}
sourcepub fn create_rel(
&self,
id: Value,
rel_name: &str,
props: HashMap<String, Value>,
dst_id: Value
) -> Result<Rel<RequestCtx>, Error>
pub fn create_rel(
&self,
id: Value,
rel_name: &str,
props: HashMap<String, Value>,
dst_id: Value
) -> Result<Rel<RequestCtx>, Error>
Creates a Rel
, with a id, relationship name, properties, and destination node id and
label. The src node of the relationship is the parent node on which the field is being
resolved.
Error
Returns an Error
of variant TypeNotExpected
if the parent object isn’t a node
Examples
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
let node_id = Value::String("12345678-1234-1234-1234-1234567890ab".to_string());
let rel_id = Value::String("1e2ac081-b0a6-4f68-bc88-99bdc4111f00".to_string());
let rel_name = "owner";
let mut rel_props = HashMap::new();
rel_props.insert("since".to_string(), Value::String("2020-01-01".to_string()));
let rel = facade.
create_rel(rel_id, rel_name, rel_props, node_id)?;
facade.resolve_rel(&rel).await
})
}
sourcepub fn create_rel_with_dst_node(
&self,
id: Value,
rel_name: &str,
props: HashMap<String, Value>,
dst: Node<RequestCtx>
) -> Result<Rel<RequestCtx>, Error>
pub fn create_rel_with_dst_node(
&self,
id: Value,
rel_name: &str,
props: HashMap<String, Value>,
dst: Node<RequestCtx>
) -> Result<Rel<RequestCtx>, Error>
Creates a Rel
, with a id, properties, and destination node. The src node of the
relationship is the parent node on which the field is being resolved.
Error
Returns an Error
of variant TypeNotExpected
if the parent object isn’t a node
Examples
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
let node_id = Value::String("12345678-1234-1234-1234-1234567890ab".to_string());
let typename = "User";
let mut props = HashMap::new();
props.insert("role".to_string(), Value::String("Admin".to_string()));
let n = facade.node(typename, props);
let rel_id = Value::String("1e2ac081-b0a6-4f68-bc88-99bdc4111f00".to_string());
let rel_name = "owns";
let mut rel_props = HashMap::new();
rel_props.insert("since".to_string(), Value::String("2020-01-01".to_string()));
let rel = facade.create_rel_with_dst_node(rel_id, rel_name, rel_props, n)?;
facade.resolve_rel(&rel).await
})
}
sourcepub fn executor(&self) -> &Executor<'_, '_, GraphQLContext<RequestCtx>>
pub fn executor(&self) -> &Executor<'_, '_, GraphQLContext<RequestCtx>>
sourcepub fn parent_node(&self) -> Result<&Node<RequestCtx>, Error>
pub fn parent_node(&self) -> Result<&Node<RequestCtx>, Error>
Returns the parent GraphQL object of the field being resolved as a Node
Errors
Returns an Error
of variant TypeNotExpected
if the parent object is not a node
Examples
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
let parent_node = facade.parent_node()?;
println!("Parent type: {:#?}",
parent_node.concrete_type_name(facade.executor().context(), facade.info()));
facade.resolve_null()
})
}
sourcepub fn resolve_null(&self) -> ExecutionResult
pub fn resolve_null(&self) -> ExecutionResult
Returns a GraphQL Null
Examples
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
// do work
// return null
facade.resolve_null()
})
}
sourcepub fn resolve_scalar<T>(&self, v: T) -> ExecutionResult where
T: Into<DefaultScalarValue>,
pub fn resolve_scalar<T>(&self, v: T) -> ExecutionResult where
T: Into<DefaultScalarValue>,
Returns a GraphQL Scalar
Examples
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
// do work
// return string
facade.resolve_scalar("Hello")
})
}
sourcepub fn resolve_scalar_list<T>(&self, v: Vec<T>) -> ExecutionResult where
T: Into<DefaultScalarValue>,
pub fn resolve_scalar_list<T>(&self, v: Vec<T>) -> ExecutionResult where
T: Into<DefaultScalarValue>,
Returns a GraphQL Scalar list
Examples
use warpgrapher::engine::resolvers::{ResolverFacade, ExecutionResult};
use warpgrapher::juniper::BoxFuture;
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
// do work
// return string
facade.resolve_scalar_list(vec![1, 2, 3])
})
}
sourcepub async fn resolve_node(&self, node: &Node<RequestCtx>) -> ExecutionResult
pub async fn resolve_node(&self, node: &Node<RequestCtx>) -> ExecutionResult
Returns a GraphQL Object representing a graph node defined by a type and a map of props.
Examples
use serde_json::json;
use std::collections::HashMap;
use warpgrapher::engine::resolvers::{ExecutionResult, ResolverFacade};
use warpgrapher::engine::value::Value;
use warpgrapher::juniper::BoxFuture;
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
// do work
let mut hm = HashMap::new();
hm.insert("name".to_string(), Value::String("John Doe".to_string()));
hm.insert("age".to_string(), Value::Int64(21));
// return node
facade.resolve_node(&facade.node("User", hm)).await
})
}
sourcepub async fn resolve_node_list(
&self,
node_list: Vec<Node<RequestCtx>>
) -> ExecutionResult
pub async fn resolve_node_list(
&self,
node_list: Vec<Node<RequestCtx>>
) -> ExecutionResult
Returns a GraphQL Object representing a list of graph node defined by a type and a map of props.
Examples
use serde_json::json;
use std::collections::HashMap;
use warpgrapher::engine::resolvers::{ExecutionResult, ResolverFacade};
use warpgrapher::engine::value::Value;
use warpgrapher::juniper::BoxFuture;
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
// do work
let mut hm = HashMap::new();
hm.insert("name".to_string(), Value::String("John Doe".to_string()));
hm.insert("age".to_string(), Value::Int64(21));
// return node
let node_list = vec![facade.node("User", hm)];
facade.resolve_node_list(node_list).await
})
}
sourcepub async fn resolve_rel(&self, rel: &Rel<RequestCtx>) -> ExecutionResult
pub async fn resolve_rel(&self, rel: &Rel<RequestCtx>) -> ExecutionResult
Returns a GraphQL Object representing a graph relationship defined by an ID, props, and a destination Warpgrapher Node.
Examples
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
// do work
let node_id = Value::String("12345678-1234-1234-1234-1234567890ab".to_string());
let mut hm1 = HashMap::new();
hm1.insert("role".to_string(), Value::String("member".to_string()));
// return rel
facade.resolve_rel(&facade.create_rel(
Value::String("655c4e13-5075-45ea-97de-b43f800e5854".to_string()),
"members", hm1, node_id)?).await
})
}
sourcepub async fn resolve_rel_list(
&self,
rels: Vec<&Rel<RequestCtx>>
) -> ExecutionResult
pub async fn resolve_rel_list(
&self,
rels: Vec<&Rel<RequestCtx>>
) -> ExecutionResult
Returns a GraphQL Object array representing Warpgrapher Rels defined by an ID, props, and a destination Warpgrapher Node.
Examples
fn custom_resolve(facade: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
// do work
let node_id1 = Value::String("12345678-1234-1234-1234-1234567890ab".to_string());
let node_id2 = Value::String("87654321-4321-4321-4321-1234567890ab".to_string());
let mut hm1 = HashMap::new();
hm1.insert("role".to_string(), Value::String("member".to_string()));
let mut hm2 = HashMap::new();
hm2.insert("role".to_string(), Value::String("leader".to_string()));
// return rel list
facade.resolve_rel_list(vec![
&facade.create_rel(
Value::String("655c4e13-5075-45ea-97de-b43f800e5854".to_string()),
"members", hm1, node_id1)?,
&facade.create_rel(
Value::String("713c4e13-5075-45ea-97de-b43f800e5854".to_string()),
"members", hm2, node_id2)?
]).await
})
}
sourcepub fn request_context(&self) -> Option<&RequestCtx>
pub fn request_context(&self) -> Option<&RequestCtx>
Returns the request context
Examples
fn custom_resolve(context: ResolverFacade<()>) -> BoxFuture<ExecutionResult> {
Box::pin(async move {
if let Some(request_context) = context.request_context() {
// use request_context
}
context.resolve_null()
})
}
Auto Trait Implementations
impl<'a, RequestCtx> !RefUnwindSafe for ResolverFacade<'a, RequestCtx>
impl<'a, RequestCtx> Send for ResolverFacade<'a, RequestCtx>
impl<'a, RequestCtx> Sync for ResolverFacade<'a, RequestCtx>
impl<'a, RequestCtx> Unpin for ResolverFacade<'a, RequestCtx>
impl<'a, RequestCtx> !UnwindSafe for ResolverFacade<'a, RequestCtx>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcepub fn borrow_mut(&mut self) -> &mut T
pub fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> Instrument for T
impl<T> Instrument for T
sourcefn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
sourcefn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
pub fn vzip(self) -> V
sourceimpl<T> WithSubscriber for T
impl<T> WithSubscriber for T
sourcefn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
Attaches the provided Subscriber
to this type, returning a
WithDispatch
wrapper. Read more
sourcefn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
Attaches the current default Subscriber
to this type, returning a
WithDispatch
wrapper. Read more