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

Example Request: Subscriptions with RedisPubSub #1340

Closed
JoJ123 opened this issue Jul 4, 2022 · 8 comments
Closed

Example Request: Subscriptions with RedisPubSub #1340

JoJ123 opened this issue Jul 4, 2022 · 8 comments

Comments

@JoJ123
Copy link
Contributor

JoJ123 commented Jul 4, 2022

Hey,
I would like to request an example of GraphQL Yoga Subscriptions with RedisPubSub and asynchronous filtering.

We managed to migrate from ApolloServer to Yoga, but we still have to rely on the withFilter Function from apollo. This is working fine, but it would be easier / cleaner if we could directly make use filter function from GraphQL Yoga. Like described here: https://www.graphql-yoga.com/docs/features/subscriptions#filter-and-map-values

import { withFilter } from 'apollo-server-express';
{
  Subscription: {
    testSub: {
      subscribe: withFilter(
        (root: any, args: any, context: GraphQLModules.Context) =>
          context.injector.get(testModuleConfig).pubsub.asyncIterator("TEST_TOPIC"),
        (root, args, context: GraphQLModules.Context) => {
          // Here we can filter
          return new Promise(resolve => resolve(true / false));
        }
      ),
    },
  },
}
@n1ru4l
Copy link
Collaborator

n1ru4l commented Jul 4, 2022

Hey @JoJ123,

PubSub works with the filter function as described on the Subscription documentation

import {PubSub} from "graphql-subscriptions"
import {filter, pipe} from "@graphql-yoga/common"

const pubSub = new PubSub()

pipe(
  pubSub.asyncIterator("foo"),
  filter(value => value.id === "3")
)

However, the TypeScript typings within the graphql-subscriptions package are incorrect, thus the above code will raise an error.
While this behavior is fixed on the master branch (through my pr a while ago), the new version still hasn't been released. If you are using TypeScript a "temporary" solution could be the usage of patch-package for fixing the typings within graphql-subscriptions. I documented this fix in a different issue on GraphQL Code Generator. Aside from that, I don't think a new version of graphql-subscriptions will be released any time soon.

We recommend using the PubSub implementation within GraphQL Yoga instead.
The EventTarget implementation for Redis is in the works and will be complete within this sprint (latest 15.07).

You can subscribe this issue and pull request for updates:

@JoJ123
Copy link
Contributor Author

JoJ123 commented Jul 4, 2022

Hi @n1ru4l
Thank you very much for this detailed answer.

In this case would it not already work to just add as any like that:

Subscription: {
    testSub: {
      subscribe: (root: any, args: any, { injector, currentUser }: GraphQLModules.Context) => {
        if (!currentUser) {
          const errorMessage = 'No user was transmitted!';
          throw new Error('NO_AUTH');
        }

        return pipe(
          injector.get(subscriptionsModuleConfig).pubsub.asyncIterator<any>("TEST_TOPIC") as any,
          filter((payload) => injector.get(SubFilterProvider).filterTests(payload as any, args, currentUser)),
        );
      },
    },
  }

Otherwise, I will keep the WithFilter from Apollo until we can migrate to the EventTarger Implementation in July.

@n1ru4l
Copy link
Collaborator

n1ru4l commented Jul 4, 2022

In this case would it not already work to just add as any like that:

This would definitely work (with the drawback of a degraded TypeScript developer experience).

@JoJ123
Copy link
Contributor Author

JoJ123 commented Jul 4, 2022

Yeah, but it could solve the next 2-3 weeks :)
Thank you so far, let's close the request.

@JoJ123 JoJ123 closed this as completed Jul 4, 2022
@n1ru4l
Copy link
Collaborator

n1ru4l commented Jul 13, 2022

@inc16sec
Copy link

inc16sec commented Nov 4, 2022

We now have an example on https://github.com/dotansimha/graphql-yoga/tree/master/examples/redis-pub-sub

How can I filter the subscription with the example above? I have a chat app and I want the message (payload) to be sent only to the matching chat_id which is passed as an argument to the subscription. Should I filter on the subscription (using filter) OR on the resolver, I do get both the payload which contains the chat_id, and the args (chat_id) in the resolver, but I which to not Publish to a topic unless the payload's chat_id matches the args chat_id, and to only receive the message on the subscription of said chat_id.
Thank you.

@n1ru4l
Copy link
Collaborator

n1ru4l commented Nov 5, 2022

@inc16sec filtering events is described in the advanced section in the Subscription documentation: https://www.the-guild.dev/graphql/yoga-server/v3/features/subscriptions#advanced

@inc16sec
Copy link

inc16sec commented Nov 5, 2022

@inc16sec filtering events is described in the advanced section in the Subscription documentation: https://www.the-guild.dev/graphql/yoga-server/v3/features/subscriptions#advanced

I see. Thank you @n1ru4l for your response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants