Releases: async-graphql/async-graphql
Releases Β· async-graphql/async-graphql
5.0
4.0
- Implement the
ConnectionNameType
andEdgeNameType
traits to specify GraphQL type names forConnection
andEdge
, which can be automatically generated usingDefaultConnectionName
andDefaultEdgeName
. - Add
#[non_exhaustive]
attribute to Request/Response types. - Introduce ability to pre-parse Request's query. #891
- Add
introspection-only
mode. #894 - Add
bson-uuid
feature to implementScalarType
forbson::Uuid
. #875 - Bump
regex
crate from1.4.5
to1.5.5
. #862 - Bump
chrono-tz
crate from0.5.3
to0.6.1
. #831 - Move the pest parser code generation step into a test. #901
- Update
log
to version0.4.16
. #903 - Added impl of
CursorType
for floats #897 - Implement
OutputType
fortokio::sync::RwLock
andtokio::sync::Mutex
. #896 - Bump
uuid
to1.0.0
. #907 - Add some options for exporting SDL. #877
- Cache parsed
ExecuteDocument
in APQ. #919 - Fixed
OneofObject
restriction on inner types being unique. #923
3.0
Changes in v3.0
:
Use the SimpleObject
macro and the InputObject
macro at the same time.
#[derive(SimpleObject, InputObject)]
#[graphql(input_name = "MyObjectInput")]
struct MyObject {
#[graphql(default = 10)]
a: i32,
b: bool,
}
Types that are not referenced will be hidden in introspection.
#[derive(SimpleObject)]
struct MyObj {
a: i32,
}
#[Object]
struct Query {
#[graphql(visible = false)]
fn obj(&self) -> MyObj {
todo!()
}
}
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
assert_eq!(
schema.execute(r#"{ __type(name: "MyObj") { name } }"#).await.into_result().unwrap().data,
value!({ "__type": null })
);
Make the API of integrations is more consistent.
Remove async-graphql-tide
.
Rework validators.
Built-in validator:
struct Query;
#[Object]
impl Query {
async fn value1(&self, #[graphql(validator(maximum = 10))] n: i32) -> i32 {
n
}
}
Custom-validator:
struct MyValidator {
expect: i32,
}
impl MyValidator {
pub fn new(n: i32) -> Self {
MyValidator { expect: n }
}
}
impl CustomValidator<i32> for MyValidator {
fn check(&self, value: &i32) -> Result<(), String> {
if *value == self.expect {
Ok(())
} else {
Err(format!("expect 100, actual {}", value))
}
}
}
struct Query;
#[Object]
impl Query {
async fn value(
&self,
#[graphql(validator(custom = "MyValidator::new(100)"))] n: i32,
) -> i32 {
n
}
}
Rework guards.
#[derive(Eq, PartialEq, Copy, Clone)]
enum Role {
Admin,
Guest,
}
pub 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())
}
}
}
#[derive(SimpleObject)]
struct Query {
#[graphql(guard = "RoleGuard::new(Role::Admin)")]
value: i32,
}
Use parameters:
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
}
}