graphback icon indicating copy to clipboard operation
graphback copied to clipboard

Subscriptions not working in GraphiQL Playground with Fastify

Open craicoverflow opened this issue 4 years ago • 11 comments

// TODO

  • Module:
  • Version: *
  • Node.js / npm versions: *
  • Example/snippet of the model that is causing issue

In the fastify-mongo-server-ts template, subscriptions appear to not be working using the GraphiQL Playground:

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field Subscription.newNote.",
      "locations": [
        {
          "line": 31,
          "column": 3
        }
      ],
      "path": [
        "newNote"
      ]
    }
  ],
  "data": null
}

This may not be an issue with Graphback, but it also might be. As such let's have this issue to ensure this is resolved. The Fastify templates are turned off until then.

Once this is resolved please check that the templates work and enable them in the CLI:

https://github.com/aerogear/graphback/blob/57de51595b51b56e211753fcc7e63f2fe3a8afaa/packages/create-graphback/src/init/starterTemplates.ts#L80

https://github.com/aerogear/graphback/blob/57de51595b51b56e211753fcc7e63f2fe3a8afaa/packages/create-graphback/src/init/starterTemplates.ts#L51

craicoverflow avatar Oct 12 '20 10:10 craicoverflow

Automatically generated comment to notify maintainers /cc @machi1990, @wtrocki

machi1990 avatar Oct 12 '20 10:10 machi1990

Hey @craicoverflow! I'd like to help solve this issue.

but it also might be

To be sure that it is not a Graphback issue I wanted to look at the resolvers which get generated. I was looking for them and as far as I could understand they get generated here. But I still am not sure how to see the actually generated resolvers file. Can you please point me to it? Thanks.

RinkiyaKeDad avatar Dec 20 '20 09:12 RinkiyaKeDad

Hi @RinkiyaKeDad!

The resolvers are created in the SchemaCRUDPlugin

craicoverflow avatar Dec 22 '20 18:12 craicoverflow

Hi @craicoverflow! There were some Typescript types related errors in SchemaCRUDPlugin. For example when adding the create subscription resolver I was getting this error in the console:

Argument of type 'IUnionTypeResolver | IEnumTypeResolver | IInputObjectTypeResolver | IObjectTypeResolver<any, any, any> | IInterfaceTypeResolver<...>' is not assignable to parameter of type 'IObjectTypeResolver<any, any, any>'.
  Type 'IUnionTypeResolver' is not assignable to type 'IObjectTypeResolver<any, any, any>'.
    Type 'IUnionTypeResolver' is not assignable to type '{ [key: string]: IFieldResolver<any, any, any, any> | IFieldResolverOptions<any, any, any>; }'.

I am not entirely sure if this is responsible for subscriptions not working. Please let me know your views on this. Till then I'll try creating a Fastify server the same way as we did in the template and if that works I think it could confirm if the problem is with the way we created the template or not.

Thanks and happy holidays!

RinkiyaKeDad avatar Dec 26 '20 11:12 RinkiyaKeDad

@RinkiyaKeDad Our resolvers work with Apollo format. Fastify (graphql-js) uses different format for subscription resolvers

https://www.apollographql.com/docs/apollo-server/data/subscriptions/

Typescript issues are just manifestation of this problem.

wtrocki avatar Dec 28 '20 12:12 wtrocki

@wtrocki but isn't the SchemaCRUDPlugin file independent of the template we use and so should not be showing the TypeScript errors?

If that is not the case can you point me to what I should look into inorder to solve this? I reckon changing the way the Graphback resolvers work for a this one particular case work would not be a good idea, right?

RinkiyaKeDad avatar Dec 28 '20 14:12 RinkiyaKeDad

We do not need to change how resolvers work. Our template need to enable subscriptions and handle them.

Cannot return null for non-nullable field Subscription.newNote

We need to map resolver function definitions to be compatible. Graphback output resolvers: https://github.com/aerogear/graphback/blob/2f8bb076b524c062e00e1cf1494d9af495bf3f12/packages/graphback-codegen-schema/src/SchemaCRUDPlugin.ts#L652

Graphback outputs resolvers to user template, so it is up to template to make them work. Fastify template is not setting resolvers right way.

For more info see https://www.apollographql.com/docs/graphql-subscriptions/

wtrocki avatar Dec 28 '20 17:12 wtrocki

If we take look on the code template expects function but receives object with subscribe method.

To prove that this is going to resolve issue you can do this in template

subscriptionObj[operation] = subscriptionObj[operation].subscribe

wtrocki avatar Dec 28 '20 17:12 wtrocki

Thanks for the detailed explanation @wtrocki. I understand what the problem is now.

I looked up on it a bit more and I think the problem is actually with mercurius and not fastify itself. I'm not sure yet but I think the fix could be simply specifying the resolvers here because like you pointed out

code template expects function but receives object

If you have a look at the plugin options mercurius provides, you'll see that the second one is the list is resolvers and that expects an object like you said before.

Please let me know if this is the way to proceed or if you have something else in mind.

We need to map resolver function definitions to be compatible

I searched regarding this too but couldn't figure out how to go ahead with it 😅

RinkiyaKeDad avatar Dec 30 '20 12:12 RinkiyaKeDad

Surprisingly mercurius documents resolvers the same way as Graphback:

https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md

Eg:

 Subscription: {
    notificationAdded: {
      subscribe: async (root, args, { pubsub }) =>
        await pubsub.subscribe('NOTIFICATION_ADDED')
    }
  }

wtrocki avatar Dec 30 '20 14:12 wtrocki

Surprisingly mercurius documents resolvers the same way as Graphback

This would mean the solution I mentioned should work I guess. Will try it out and raise a PR.

RinkiyaKeDad avatar Dec 31 '20 08:12 RinkiyaKeDad