Juniper: #[juniper::graphql_object] != #[derive(juniper::GraphQLObject)]

Created on 20 Mar 2020  路  6Comments  路  Source: graphql-rust/juniper

Code like this in master branch:

pub struct Data {
   pub value: String,
}

#[juniper::graphql_object]
impl Data {
    pub fn value(&self) -> String {
        self.value
    }
}

#[derive(juniper::GraphQLObject)]
pub struct User {
   pub username: String,
   pub values: Vec<Data>,
}

Produce an error:

the trait bound `Data: juniper::types::async_await::GraphQLTypeAsync<__S>` is not satisfied
required because of the requirements on the impl of `juniper::types::async_await::GraphQLTypeAsync<__S>` for `std::vec::Vec<Data>`
required because of the requirements on the impl of `juniper::types::async_await::GraphQLTypeAsync<__S>` for `&std::vec::Vec<Data>`

`match` arms have incompatible types
expected enum `std::result::Result<juniper::value::Value<__S>, juniper::executor::FieldError<__S>>`
   found enum `std::result::Result<_, juniper::executor::FieldError<juniper::value::scalar::DefaultScalarValue>>`
type parameters must be constrained to match other types
for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

But code like this works:

#[derive(juniper::GraphQLObject)]
pub struct Data {
   pub value: String,
}

#[derive(juniper::GraphQLObject)]
pub struct User {
   pub username: String,
   pub values: Vec<Data>,
}
async blocker bug

Most helpful comment

@LegNeato it's not about asyncness, but rather because one of the macros derives code for DefaultScalarValue and another oned for __S: ScalarValue. Then the first is used as the field of the second one, so we have the situation when we need funtion being abstracted over __S: ScalarValue, but in fact we can call inside only something with DefaultScalarValue.

I'm going to fix this once I finish with interfaces.

@loafofpiecrust at the moment, you should specialize the generic implementation by providing attributes argument scalar = DefaultScalarValue. This way both implementations will be derived for DefaultScalarValue, so no conflict will happen.

All 6 comments

You need to add "value" as an async function in the proc macro case.

This will be fixed when I rip out the sync resolvers.

We are not going to be removing the sync code.

I'm having the same problem where I want to nest a type defined with #[juniper::graphql_object] with only async functions inside one defined with `

[derive(juniper::GraphQLObject)]` and I get these same kinds of errors.

Is this something we want to fix or not?

If you add noasync to the first case (a la https://github.com/graphql-rust/juniper/blob/4d77a1a9b9b0e60cbeb200527289bd45afec4141/juniper/src/schema/schema.rs#L134) then does it work?

@LegNeato it's not about asyncness, but rather because one of the macros derives code for DefaultScalarValue and another oned for __S: ScalarValue. Then the first is used as the field of the second one, so we have the situation when we need funtion being abstracted over __S: ScalarValue, but in fact we can call inside only something with DefaultScalarValue.

I'm going to fix this once I finish with interfaces.

@loafofpiecrust at the moment, you should specialize the generic implementation by providing attributes argument scalar = DefaultScalarValue. This way both implementations will be derived for DefaultScalarValue, so no conflict will happen.

Ah yeah, that's what I figured but wanted to confirm there wasn't any wonkiness going on with our async handling

Was this page helpful?
0 / 5 - 0 ratings