I'm making a GraphQL backend in Apollo, and I'd like to use subscriptions. I followed Apollo's docs, and I've gotten basic subscriptions working using graphql-subscriptions
. This package also comes with filtering via the built-in withFilter
function. However, I don't want to emit all of the data published via PubSub
because some of this data is used for filtering purposes only.
Ex.
// GraphQL Schema
type Subscription {
mySubscription(filter: MySubscriptionFilter!): ID!
}
// Publishing the event
pubsub.publish("MY_SUBSCRIPTION", { id: "2092330", username: "asdf", roles: [ "USER", "MODERATOR" ] });
// Handling the event for a subscription
const resolvers = {
Subscriptions: {
mySubscription: {
subscribe: withFilter(
() => pubsub.asyncIterator("MY_SUBSCRIPTION"),
(payload, variables) => {
return customFiltering(payload, variables);
}
)
}
}
}
This returns an object with the type: { id, username, roles }
. However, the username and roles fields are only used for filtering. I ultimately need to return an object of type { mySubscription: id }
, because that's what my GraphQL schema says.
Is there a way to do something like this?
// Handling the event for a subscription
const resolvers = {
Subscriptions: {
mySubscription: {
subscribe: withFilter(
() => pubsub.asyncIterator("MY_SUBSCRIPTION"),
(payload, variables) => {
return customFiltering(payload, variables);
}
).map(x => {
return { mySubsription: x.id }
}) // Map function where x is the payload from the pubsub
}
}
}
Whoops, it looks like I overlooked the resolve function in a subscription.
From the graphql-subscriptions
github page
You can also manipulate the published payload, by adding resolve methods to your subscription:
const SOMETHING_UPDATED = 'something_updated';
export const resolvers = {
Subscription: {
somethingChanged: {
resolve: (payload, args, context, info) => {
// Manipulate and return the new value
return payload.somethingChanged;
},
subscribe: () => pubsub.asyncIterator(SOMETHING_UPDATED),
},
},
}