-
-
Notifications
You must be signed in to change notification settings - Fork 499
Description
Description of the feature
Recently, many GraphQL frameworks and libraries are adopting semantic nullability support with @semanticNonNull
, namely Relay and Apollo Kotlin at the client, Caliban and Grats at the server. There are also tools like graphql-sock and graphql-toe to help existing libraries work with semantic nullability. While it's already possible to mimic the functionality in async-graphql by manually injecting the directives, since it's a huge pain putting them everywhere and making everything optional, adding macro support for the feature in async-graphql would be very helpful.
Code example (if possible)
TODO: how would we make the feature opt-in? A Cargo feature? An attribute on macros?
struct MyObject;
#[Object]
impl MyObject {
async fn value(&self) -> i32 {
42
}
async fn optional_value(&self) -> Option<i32> {
Some(42)
}
async fn fallible_value(&self, input: String) -> Result<i32> {
Ok(input
.parse()
.map_err(|err: ParseIntError| err.extend_with(|_, e| e.set("code", 400)))?)
}
async fn fallible_optional_value(&self, input: Option<String>) -> Result<Option<i32>> {
match input {
Some(input) => Ok(input
.parse()
.map_err(|err: ParseIntError| err.extend_with(|_, e| e.set("code", 400)))?),
None => Ok(None)
}
}
}
This should result in the following schema:
type MyObject {
# infallible values as strict non-null (no change)
value: Int!
# optional values as nullable (no change)
optionalValue: Int
# fallible values as semantic non-null, marked with a directive (new!)
fallibleValue: Int @semanticNonNull
# fallible optional value as nullable (no change)
fallibleOptionalValue: Int
}
In addition, Result<Vec<T>>
, Vec<Result<T>>
, and Result<Vec<Result<T>>>
should be handled using the levels
argument in the directive.
Result<Vec<T>> => [T!] @semanticNonNull(levels: [0])
Vec<Result<T>> => [T]! @semanticNonNull(levels: [1])
Result<Vec<Result<T>>> => [T] @semanticNonNull(levels: [0, 1])