Async-graphql: Federation not working with MergedObject mutation

Created on 20 Oct 2020  路  5Comments  路  Source: async-graphql/async-graphql

After the fix of #315 I'm seeing another issue with federation and mutation generated by MergedObject.

Expected Behavior

If the query has at least one entity definition, I would expect federation to be enabled. I would expect the mutation to be irrelevant.

Actual Behavior

The above works fine until I add a mutation made using MergedObject. When I create the mutation like this:

#[derive(MergedObject, Default)]
struct Mutation(FruitMutation, VegetableMutation);

Then federation doesn't seem to get auto-enabled anymore, which means no _service or _entities fields are returned. When I manually enable federation on the schema builder, the fields _service or _entities exist, but the _Entity union type has no members.

Steps to Reproduce the Problem

  1. Create a query with at least one #[graphql(entity)] function.
  2. Add a mutation with at least one function.
  3. Generate an introspection result and observe the correctly enabled federation.
  4. Wrap the mutation in another mutation using MergedObject.
  5. Generate an introspection result and observe that federation now seems to be disabled (unless manually enabled on the schema builder).

Specifications

  • Version: 2.0.6
  • Platform: macOS
bug

All 5 comments

I can't reproduce this problem. Is it because I did something wrong?

    #[derive(SimpleObject)]
    struct Fruit {
        id: ID,
        name: String,
    }

    struct Query;

    #[Object]
    impl Query {
        #[graphql(entity)]
        async fn get_fruit(&self, id: ID) -> Fruit {
            Fruit {
                id,
                name: "Apple".into(),
            }
        }
    }

    #[derive(Default)]
    struct Mutation1;

    #[Object]
    impl Mutation1 {
        async fn action1(&self) -> bool {
            true
        }
    }

    #[derive(Default)]
    struct Mutation2;

    #[Object]
    impl Mutation2 {
        async fn action2(&self) -> bool {
            true
        }
    }

    #[derive(MergedObject, Default)]
    struct Mutation(Mutation1, Mutation2);

    let schema = Schema::new(Query, Mutation::default(), EmptySubscription);
    assert!(schema.execute("{ _service { sdl }}").await.is_ok());

Ah, sorry. Apparently I didn't test enough to make a proper minimal example. But here we go now.

The change to your example that triggers the issue is:

  • The mutation returns the same type as the entity function.
#[derive(SimpleObject)]
struct Fruit {
    id: ID,
    name: String,
}

struct Query;

#[Object]
impl Query {
    #[graphql(entity)]
    async fn get_fruit(&self, id: ID) -> Fruit {
        Fruit {
            id,
            name: "Apple".into(),
        }
    }
}

#[derive(Default)]
struct Mutation1;

#[Object]
impl Mutation1 {
    async fn action1(&self) -> Fruit {
        Fruit {
            id: ID("hello".into()),
            name: "Apple".into(),
        }
    }
}

#[derive(MergedObject, Default)]
struct Mutation(Mutation1);

#[async_std::main]
async fn main() {
    // This works
    let schema = Schema::new(Query, Mutation1, EmptySubscription);
    assert!(schema.execute("{ _service { sdl }}").await.is_ok());

    // This fails
    let schema = Schema::new(Query, Mutation::default(), EmptySubscription);
    assert!(schema.execute("{ _service { sdl }}").await.is_ok());
}

Thank you for your feedback, I am solving it.

Thank you, this is a very serious bug that I accidentally added today. 馃槀
I have fixed this problem in v2.0.7 version.

No worries 馃檪

Thanks for the super quick resolution. I can confirm that everything is working great now with 2.0.7. 馃帀

Was this page helpful?
0 / 5 - 0 ratings