Scoping _only_ by `subscription_scope`
jscheid opened this issue · 7 comments
Is your feature request related to a problem? Please describe.
We have several subscription endpoints, each with different names (obviously) and different argument types, but all returning the same payload type. Each subscription is scoped (using subscription_scope
) to an ID unique per subscription (not only unique per subscription endpoint.)
We have helper code to generate events for these subscriptions, shared between the different subscription endpoints. Unfortunately, this helper code needs to be aware of the subscription field name and arguments in order to be able to trigger events - knowledge of the unique ID scope isn't sufficient when it could be, since the unique ID alone is enough to disambiguate between different concurrent subscriptions. This complicates our code needlessly.
Is there a mechanism to trigger events using only the scope, ignoring field name and arguments? If not, could one be added?
Describe the solution you'd like
One solution might be a configuration on the subscription along the lines of subscription_scope_is_unique
, that would then ignore field and arguments for trigger matching. Another solution would be a way to override the field name and argument hash per subscription endpoint, which would let us set both to common (dummy) values.
Describe alternatives you've considered
Nothing comes to mind, sorry if I'm missing something obvious.
Additional context
N/A
Hey, great question. I think this should be possible by implementing def self.topic_for
in your subscription classes (or in the inheritance chain somewhere). That method is called with a bunch of runtime info and returns the string which is used for "routing" updates.
Here's the source for that method:
graphql-ruby/lib/graphql/schema/subscription.rb
Lines 134 to 153 in eff5c91
I think if you implemented it to only return scope.to_s
, you'd have the desired setup. Want to give that a try?
Hey Robert, yes that's definitely an improvement because we no longer have to match the arguments - thank you for reminding me of this feature. Unfortunately it doesn't work for the field name, if I change that to some bogus value (in the trigger) I'm getting:
GraphQL::Subscriptions::InvalidTriggerError: No subscription matching trigger: foo (looked for Subscription.foo)
Any other ideas?
Hmm, too bad -- it's definitely supposed to support this case! Could you share the full backtrace of that error?
It gets raised here - makes sense in a way because there's no such field on the subscriptions object.
graphql-ruby/lib/graphql/subscriptions.rb
Lines 72 to 75 in eff5c91
(We're calling this directly from our app code so the rest of the backtrace isn't relevant.)
If I set it to some existing (unrelated) subscription field's name, no error is raised but I'm also not seeing any subscription updates anymore.
Thanks for those details. How about calling .trigger
with one of the field names that uses the shared scope:
value? That way, GraphQL-Ruby can find an example Subscription class to call .topic_for
on. I added a test to GraphQL-Ruby for what I think you're trying to do here: 879096d and that approach worked for me. Let me know what you find!
Derp - right, without knowing the Subscription class it couldn't know how to encode the topic. I've done that, by sifting through Subscriptions
fields to find one whose class includes our shared module, and seems to work fine! I'll close this for now, thanks for your help!