Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscription types incompatible with graphql-subscription's PubSub #7197

Closed
sarink opened this issue Dec 12, 2021 · 9 comments
Closed

Subscription types incompatible with graphql-subscription's PubSub #7197

sarink opened this issue Dec 12, 2021 · 9 comments
Labels
waiting-for-answer Waiting for answer from author

Comments

@sarink
Copy link

sarink commented Dec 12, 2021

The latest version of graphql-code-generator has changed the subscribe function return type to AsyncIterable<TResult> | Promise<AsyncIterable<TResult>>;

However, when using apollo's graphql-subscriptions lib, the type returned from their pubsub-engine is AsyncIterator https://github.com/apollographql/graphql-subscriptions/blob/master/src/pubsub-engine.ts#L8

AsyncIterable and AsyncIterator types are incompatible.

Example (this code will throw a type error):

const pubsub = new PubSub();

const typeDefs = gql`
  type Subscription {
    root: String
  }
`

const resolvers: Resolvers = {
  Subscription: {
    root: {
      subscribe: () => {
        // Type 'AsyncIterator<unknown, any, undefined>' is not assignable to type 'AsyncIterable<any> | Promise<AsyncIterable<any>>'.
        return pubsub.asyncIterator('root');
      }
    }
  }
};

What's the recommended workaround for this issue?

@armintan
Copy link

I do habe the same problem ... any recommendations?

@Thompson-Jordon
Copy link

Thompson-Jordon commented Dec 27, 2021

I also have this same issue.

import { SubscriptionResolvers } from '../../generated/graphql'
import { Context } from '../context'

export const NEW_POINT = 'NEW_POINT'

export const Subscription: SubscriptionResolvers<Context> = {
  newPoint: {
    subscribe: (_,__,context) => context.pubsub.asyncIterator(NEW_POINT)
  },
}

I can get the subscription to work if I alter the Graphql Codegen type file to accept 'AsyncIterator<unknown, any, undefined>' This is not a fix I still need to understand how to get it to work without altering the code manually.

@rustic0la
Copy link

rustic0la commented Dec 30, 2021

#7015 (comment)
This is the discussion about the change that resulted in incompatibility between types mentioned above:
SubscriptionSubscribeFn return type been changed from AsyncIterator<TResult> | Promise<AsyncIterator<TResult>> to AsyncIterable<TResult> | Promise<AsyncIterable<TResult>>. But as graphql-subscriptions considered to be a legacy implementation for subscriptions, the possible solution might be making a patch for the library that could undo the change. More details in the thread

@Urigo
Copy link
Collaborator

Urigo commented Jan 2, 2022

@mpokrovsky I think graphql-subscriptions 3.0 might be happening soon and I think it includes the changes from @n1ru4l

Could you check if using the current state of their PR solves this issue? apollographql/graphql-subscriptions#250

@dotansimha dotansimha added the waiting-for-answer Waiting for answer from author label Jan 4, 2022
@Mad-Kat
Copy link

Mad-Kat commented Apr 13, 2022

In the meantime you could use something like this:

subscribe: () => ({
        [Symbol.asyncIterator]: () => pubsub.asyncIterator<{ numberIncremented: number }>('NUMBER_INCREMENTED'),
      }),

@n1ru4l
Copy link
Collaborator

n1ru4l commented Apr 13, 2022

@Mad-Kat This would be a working, but rather an ugly workaround. You should not tailor your code and add overhead for pleasing a library with wrong typings.

I recommend everyone to read through #7015 for a full breakdown of the situation and migrate off graphql-subscriptions or use the mentioned patch-package for fixing the typings.

@maxpain
Copy link

maxpain commented Jun 20, 2022

Any updates?

@n1ru4l
Copy link
Collaborator

n1ru4l commented Jun 20, 2022

I will close this issue as there is nothing wrong within graphql-code-generator.

@loucadufault
Copy link

Workaround proposed in above #7197 (comment) with graphql-subscriptions withFilter:

import { withFilter } from 'graphql-subscriptions';

export const resolvers = {
  Subscription: {
    somethingChanged: {
      subscribe: () => ({
        [Symbol.asyncIterator]: withFilter(
          (_, args) => pubsub.asyncIterator(`${SOMETHING_CHANGED_TOPIC}.${args.relevantId}`),
          (payload, variables: SubscriptionSomethingChangedArgs) => payload.somethingChanged.id === variables.relevantId,
        ),
      }),
    },
  },
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting-for-answer Waiting for answer from author
Projects
None yet
Development

No branches or pull requests

10 participants