3b7ed74d11
- examples to fix still - error_extensions.md ResultExt example does not compile! - trait ErrorExtensions is not implemented for ParseIntError - dataloader - requires sqlx to work. So we either "stub" it OR we rewrite them simpler to use a simple "faux" db library
2.1 KiB
2.1 KiB
字段守卫(Field Guard)
你可以为Object
, SimpleObject
, ComplexObject
和Subscription
的字段定义守卫
,它将在调用字段的 Resolver 函数前执行,如果失败则返回一个错误。
# extern crate async_graphql;
# use async_graphql::*;
#[derive(Eq, PartialEq, Copy, Clone)]
enum Role {
Admin,
Guest,
}
struct RoleGuard {
role: Role,
}
impl RoleGuard {
fn new(role: Role) -> Self {
Self { role }
}
}
#[async_trait::async_trait]
impl Guard for RoleGuard {
async fn check(&self, ctx: &Context<'_>) -> Result<()> {
if ctx.data_opt::<Role>() == Some(&self.role) {
Ok(())
} else {
Err("Forbidden".into())
}
}
}
用guard
属性使用它:
# extern crate async_graphql;
# use async_graphql::*;
# #[derive(Eq, PartialEq, Copy, Clone)]
# enum Role { Admin, Guest, }
# struct RoleGuard { role: Role, }
# impl RoleGuard { fn new(role: Role) -> Self { Self { role } } }
# #[async_trait::async_trait]
# impl Guard for RoleGuard { async fn check(&self, ctx: &Context<'_>) -> Result<()> { todo!() } }
#[derive(SimpleObject)]
struct Query {
/// 只允许Admin访问
#[graphql(guard = "RoleGuard::new(Role::Admin)")]
value1: i32,
/// 允许Admin或者Guest访问
#[graphql(guard = "RoleGuard::new(Role::Admin).or(RoleGuard::new(Role::Guest))")]
value2: i32,
}
从参数中获取值
有时候守卫需要从字段参数中获取值,你需要像下面这样在创建守卫时传递该参数值:
# extern crate async_graphql;
# use async_graphql::*;
struct EqGuard {
expect: i32,
actual: i32,
}
impl EqGuard {
fn new(expect: i32, actual: i32) -> Self {
Self { expect, actual }
}
}
#[async_trait::async_trait]
impl Guard for EqGuard {
async fn check(&self, _ctx: &Context<'_>) -> Result<()> {
if self.expect != self.actual {
Err("Forbidden".into())
} else {
Ok(())
}
}
}
struct Query;
#[Object]
impl Query {
#[graphql(guard = "EqGuard::new(100, value)")]
async fn get(&self, value: i32) -> i32 {
value
}
}