graphql-redis-subscriptions
graphql-redis-subscriptions copied to clipboard
pub/sub type safety improvements
I'm working to improve the type safety of our RedisPubSub integration and have found a simple pattern that I believe may be useful to other people.
Problem
The distance between publishing and subscribing/consuming makes it easy to introduce typos and mismatched payloads.
Workaround
Define a list of trigger names with associated payload types:
type TriggeredPayloads = {
helloWorld: string;
};
type TypedRedisPubSub = RedisPubSub & {
publish: <T extends keyof TriggeredPayloads>(
topic: T,
payload: TriggeredPayloads[T],
) => Promise<void>;
asyncIterator: <T extends keyof TriggeredPayloads>(topic: T) => AsyncIterator<T>;
};
const myPubSub = new RedisPubSub() as TypedRedisPubSub;
// ok
myPubSub.publish('helloWorld', 'Bonjour');
// not ok
myPubSub.publish('helloworld', 'Bonjour');
myPubSub.publish('helloWorld', true);
// ok
myPubSub.asyncIterator('helloWorld');
// not ok
myPubSub.asyncIterator('helloworld');
Feature Request
It would be nice if the RedisPubSub constructor accepted a generic containing a record of supported triggers and payloads:
type TriggeredPayloads = {
helloWorld: string;
};
const myPubSub = new RedisPubSub<TriggeredPayloads>();
The optimalbits/bull library has a similar problem (message passing between job producers & workers) and also implements a solution like this.
Caveats
- This only helps codebases that contain both the publisher and the subscriber
- This does not solve race conditions during a deploy where the new version includes payload changes