-
Notifications
You must be signed in to change notification settings - Fork 426
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make graphql_object macro supports deriving object field resolvers #652
base: master
Are you sure you want to change the base?
Make graphql_object macro supports deriving object field resolvers #652
Conversation
My editor uses `rustfmt` to format on save, but `rustfmt` doesn't pickup edition specified in `Cargo.toml` properly.
Not sure how to add reviewers, would be great if anyone can help. Thanks! ^^ @LegNeato @jmpunkt @Victor-Savu While I was working on the PR, I also noticed a few potential issues. But I am not sure who to talk to or maybe they are actually intended or work-in-progress features:
#[derive(GraphQLObject)]
struct Object {
value: i32,
} should be the same as #[derive(GraphQLObject)]
#[graphql(scalar = juniper::DefaultScalarValue)] // <---- here
struct Object {
value: i32,
} |
|
Thanks @jmpunkt ! Re 2: Given the following code: mod test {
#[derive(juniper::GraphQLObject)]
#[graphql(scalar = juniper::DefaultScalarValue)]
struct WithLifetime<'a> {
value: &'a str,
}
struct Query;
#[juniper::graphql_object(scalar = juniper::DefaultScalarValue)]
impl<'a> Query {
fn with_lifetime(&self) -> WithLifetime<'a> {
WithLifetime { value: "blub" }
}
}
} Here is the compile error, which I think it is related to the async resolver (but can be wrong):
Here is the generated impl<'a> juniper::GraphQLTypeAsync<juniper::DefaultScalarValue> for Query
where
juniper::DefaultScalarValue: Send + Sync,
Self: Send + Sync,
{
fn resolve_field_async<'b>(
&'b self,
info: &'b Self::TypeInfo,
field: &'b str,
args: &'b juniper::Arguments<juniper::DefaultScalarValue>,
executor: &'b juniper::Executor<Self::Context, juniper::DefaultScalarValue>,
) -> juniper::BoxFuture<'b, juniper::ExecutionResult<juniper::DefaultScalarValue>>
where
juniper::DefaultScalarValue: Send + Sync,
{
use futures::future;
use juniper::GraphQLType;
match field {
"withLifetime" => {
let res: WithLifetime<'a> = (|| WithLifetime { value: "blub" })();
let res2 = juniper::IntoResolvable::into(res, executor.context());
let f = async move {
match res2 {
Ok(Some((ctx, r))) => {
let sub = executor.replaced_context(ctx);
sub.resolve_with_ctx_async(&(), &r).await
}
Ok(None) => Ok(juniper::Value::null()),
Err(e) => Err(e),
}
};
use futures::future;
future::FutureExt::boxed(f)
}
_ => {
{
::std::rt::begin_panic_fmt(&::core::fmt::Arguments::new_v1(
&["Field ", " not found on type "],
&match (
&field,
&<Self as juniper::GraphQLType<juniper::DefaultScalarValue>>::name(
info,
),
) {
(arg0, arg1) => [
::core::fmt::ArgumentV1::new(arg0, ::core::fmt::Display::fmt),
::core::fmt::ArgumentV1::new(arg1, ::core::fmt::Debug::fmt),
],
},
))
};
}
}
}
} |
While I like the idea of this in general, I think it massively complicates the UX for folks to save on some typing. This reminds me a lot of Rust accessors and transparent newtypes. Rust itself requires boilerplate ( Personally, I like how simple and explicit the UX is right now--either graphql projection is trivial and the derive suffices or it is complex and everything is right there in the I'm happy to entertain a patch if we can keep this simple and explicit. I'm not sure we can get there with rust proc macros as-is though 🤷 |
@LegNeato Thanks for your reply, I understand your concern and agree that Juniper should not be opinionated. However, since For example juniper can generate Let me know what you think. Thanks! |
can we have multiple file1: #[derive(GraphQLObjectInfo)]
#[graphql(scalar = DefaultScalarValue)]
struct Obj {
regular_field: bool,
}
#[juniper::graphql_object(derive_fields)]
impl Obj {
fn custom_field_resolve() -> bool {
true
}
} file2: #[juniper::graphql_object(derive_fields)]
impl Obj {
fn other_field_resolve() -> bool {
true
}
} |
This PR enhance the
graphql_object
macro to optionally derive field resolvers for fields defined in the object type struct.I am pretty new to rust, please let me know if I have done anything incorrect. And I am not a native speaker of english, feel free to correct the wording of my comments. Cheers!
Related: #553