A graphql subscriptions implementation using postgres and apollo's graphql-subscriptions.
This package implements the PubSubEngine Interface from the graphql-subscriptions package and also the new AsyncIterator interface. It allows you to connect your subscriptions manger to a postgres based Pub Sub mechanism to support multiple subscription manager instances.
- Properly Maintained
- Small In Size
- Larger Payload Problem Solved (I use pg table for the payload. So now larger payload can pass) - (PG Default Notify has size limit, that's why you can't provide larger payload.);
- Fully TypeScript Support
- Worked with any framework (ExpressJS, NestJS)
npm i graphql-pg-subscriptions
First of all, follow the instructions in graphql-subscriptions to add subscriptions to your app.
Afterwards replace PubSub
with PostgresPubSub
:
// Before
import { PubSub } from "graphql-subscriptions";
export const pubsub = new PubSub();
//After
import { PostgresPubSub } from "graphql-postgres-subscriptions";
import { Client } from "pg";
const client = new Client({
user: 'dbuser',
host: 'database.server.com',
database: 'mydb',
password: 'secretpassword',
port: 3211,
});
client.connect();
const pubsub = new PostgresPubSub({ client, maxListeners: 15 });
//You can increase max event listeners if you need, default is 15
The second argument to new PostgresPubSub()
is the commonMessageHandler
. The common message handler gets called with the received message from PostgreSQL.
You can transform the message before it is passed to the individual filter/resolver methods of the subscribers.
This way it is for example possible to inject one instance of a DataLoader which can be used in all filter/resolver methods.
const getDataLoader = () => new DataLoader(...)
const commonMessageHandler = ({attributes: {id}, data}) => ({id, dataLoader: getDataLoader()})
const pubsub = new PostgresPubSub({ client, commonMessageHandler });
export const resolvers = {
Subscription: {
somethingChanged: {
resolve: ({ id, dataLoader }) => dataLoader.load(id)
}
}
};
PostgresPubSub
instances emit a special event called "error"
. This event's payload is an instance of Javascript's Error
. You can get the error's text using error.message
.
const ps = new PostgresPubSub({ client });
ps.subscribe("error", err => {
console.log(err.message); // -> "payload string too long"
}).then(() => ps.publish("a", "a".repeat(9000)));
For example you can log all error messages (including stack traces and friends) using something like this:
ps.subscribe("error", console.error);
- Author - Siam Ahnaf
- Website - https://www.siamahnaf.com/
- Twitter - https://twitter.com/siamahnaf198
- Github - https://github.com/siamahnaf