简体   繁体   中英

Apollo graphQL Server subscription initial response

I've successfully got graphQL subscriptions to work with help of the documentation.

The subscription returns a pubsub.asyncIterator("MY_TOPIC"), which I then can send messages trough. Now I would like to send the current value to the new subscriber, and only the new subscriber, on subscription.

As the pubsub.asyncIterator("MY_TOPIC")() is a shared async iterator I guess I need a wrapper, which itsef is an async iterator, which returns the current value and thereafter "becomes" the shared pubsub.asyncIterator("MY_TOPIC")().

Any ideas on how to accomplish that?

const mySubscription = {
  subscribe: async (parent, args, context, info) => {
    return context.pubsub.asyncIterator("MY_TOPIC")
  },
  resolve: payload => {
    return payload
  },
}

EDIT: It seems like sometime a good night of sleep is worth a lot.

const mySubscription = {
  subscribe: async (parent, args, context, info) => {
    return (async function* () {
      yield 123; //let this be my current state
      for await (const val of context.pubsub.asyncIterator("MY_TOPIC")) {
        yield val;
      }
    })()
  },
  resolve: payload => {
    return payload
  },
}

As far as I can see I just create a wrapper generator, which returns my desired value and afterwards iterates over the pubsub async iterator. I tried that before, but forgot about the await in the for await of loop. And obviously the pubsub AsyncIterator is not syncronously iterable. Are there any sideffects I'm missing?

It sounds like you need a filter for your subscription, have a look at the example here ...

It may look like this:

import { withFilter } from 'graphql-subscriptions';

const currentUsers = [];
const resolvers = {
  Subscription: {
    myTopic: {
      subscribe: withFilter(
        () => pubsub.asyncIterator('MY_TOPIC'),
        (payload, variables) => {
          // Only push an update if it is a new subscriber
          if (!currentUsers.includes(variables.username)) {
            currentUsers.push(variables.username);
            return true;
          }
          return false;
        },
      ),
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM