eddeee888 / graphql-code-generator-plugins

List of GraphQL Code Generator plugins that complements the official plugins.
MIT License
51 stars 12 forks source link

Subscription resolver not working as function #68

Closed trixobird closed 1 year ago

trixobird commented 1 year ago

I followed the guild.dev guide and everything were good. So in book/schema.graphql I added

extend type Subscription {
    bookReadEvent: Boolean!
}

and upon generation I got a new filew in book/Subscription folder named bookReadEvent.ts

export const bookReadEvent: NonNullable<SubscriptionResolvers['bookReadEvent']> = async (_parent, _arg, _ctx) => {
};

I am not able to make it work as a function, nomatter what I added there. For example when I put this

//@ts-ignore
export const bookReadEvent: NonNullable<SubscriptionResolvers['bookReadEvent']> = async (_parent, _arg, _ctx) => ({
  subscribe: () => pubSub.subscribe('userLoginChanged'),
  resolve: () => true
});

I was getting

{
  "errors": [
    {
      "message": "Subscription field must return Async Iterable. Received: undefined.",
      "locations": [
        {
          "line": 1,
          "column": 28
        }
      ],
      "path": [
        "bookReadEvent"
      ]
    }
  ]
}

right when I executing the subsription call. I was able to make to work like this:

export const bookReadEvent: NonNullable<SubscriptionResolvers['bookReadEvent']> = async (_parent, _arg, _ctx) => ({
  subscribe: () => pubSub.subscribe('userLoginChanged'),
  resolve: () => true
});

where pubSub is

export const pubSub = createPubSub<{
  userLoginChanged: [boolean]
}>()

The generated type support both, so it seems that I am missing something. Could you help me please? Happy to add it to documentation afterwards as example.

eddeee888 commented 1 year ago

Hello @trixobird , you are right: the generated shape of Subscription is incorrect. I will make an update soon.

It is supposed to look like this:

// Option 1 - Will be in the next fix
export const bookReadEvent: NonNullable<SubscriptionResolvers["bookReadEvent"]> = {
  subscribe: async (_parent, _arg, _ctx) => {
    // ... Subscription implementation here
  },
};

// Option 2
export const bookReadEvent: NonNullable<SubscriptionResolvers["bookReadEvent"]> = () => ({
  subscribe: async (_parent, _arg, _ctx) => {
    // ... Subscription implementation here
  },
});

For your current issue, are you following the Subscription guide on GraphQL Yoga? If so, can you try this and see if it works:

export const bookReadEvent: NonNullable<SubscriptionResolvers["bookReadEvent"]> = {
  subscribe: () => pubSub.subscribe('userLoginChanged'),
  resolve: (payload) => payload
};
eddeee888 commented 1 year ago

I have released an alpha version to fix the default Subscription resolver generation issue.

If you have a chance, do you mind trying it out:

  1. Install the package
    yarn add @eddeee888/gcg-typescript-resolver-files@pr73-run161-1
  2. Comment out existing resolver implementation
  3. Run codegen
  4. Check that the new generated function is this:
    export const bookReadEvent: NonNullable<SubscriptionResolvers["bookReadEvent"]> = {
    subscribe: async (_parent, _arg, _ctx) => {
    /* Implement Subscription.bookReadEvent resolver logic here */
    },
    };
  5. Try updating it to this to see if it works:
    export const bookReadEvent: NonNullable<SubscriptionResolvers["bookReadEvent"]> = {
    subscribe: () => pubSub.subscribe('userLoginChanged'),
    resolve: (payload) => payload
    };

Let me know how you go! :)

eddeee888 commented 1 year ago

Hi @trixobird , does the alpha version work for you? :)

eddeee888 commented 1 year ago

Version 0.4 has a fix for this. Please try and let me know if there's still a problem

yarn add -D @eddeee888/gcg-typescript-resolver-files@0.4.0