Directive
We can use directives as middleware.
It is useful in the following use cases.
- Authorization
- Validation
- Caching
- Logging, metrics
- etc.
If we don't want to expose a specific field, we can define the following directive.
src/graphql/directive/hidden.rs
#![allow(unused)] #![allow(warnings, unused)] fn main() { use crate::graphql::*; use rusty_gql::*; #[derive(Clone)] struct Hidden; impl Hidden { fn new() -> Box<dyn CustomDirective> { Box::new(Hidden {}) } } #[async_trait::async_trait] impl CustomDirective for Hidden { async fn resolve_field( &self, _ctx: &Context<'_>, _directive_args: &BTreeMap<String, GqlValue>, resolve_fut: ResolveFut<'_>, ) -> ResolverResult<Option<GqlValue>> { resolve_fut.await.map(|_v| None) } } }
schema.graphql
type User {
name: String!
password_hash: String @hidden
}
directive @hidden on FIELD_DEFINITION | OBJECT
Need to pass a HashMap of directives when Container::new in main.rs.
A Key is the directive name, a value is the directive struct.
main.rs
async fn main() { ... let mut custom_directive_maps = HashMap::new(); custom_directive_maps.insert("hidden", Hidden::new()); let container = Container::new( schema_docs.as_slice(), Query, Mutation, EmptySubscription, custom_directive_maps, // path here ) .unwrap(); ... }