-
Notifications
You must be signed in to change notification settings - Fork 437
Make graphql_object macro supports deriving object field resolvers #652
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
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