This is a work in progress article. Publishing before it's finished is an experiment for me. I'm happy to take feedback on Discord.
There are three methods available with Postgraphile for pushing data from the server to the client:
Of course the GraphQL protocol and frameworks like Apollo supports polling queries from the client side.
first of all live queries are not part of the official GraphQL protocol but subscriptions are
using multiple live queries cause performance issues but depends it on implementation. In contrast, custom subscriptions have the benefit that we can fine tune how often they fire on a Postgres trigger level, additionally to that we can further add optimisations on the GraphQL resolver level
the official Postgraphile docs says
official realtime provider plugin,
@graphile/subscriptions-lds
, monitors a “logical replication slot” from PostgreSQL”
The issue with this is that the replication slot usually is not available for managed Postgres instances like AWS Aurora Serverles Postgres so you can’t use @graphile/subscriptions-lds
based live queries with managed databases
With simple subscriptions there is no need for any manual labour, just enable them in the Postgraphile config and it’s done. Postgraphile will provide subscriptions to all tables. It’s good for prototyping but it can be inefficient.
They are a bit more work but you get a few benefits:
Let’s build a simple chat app. We will have a messages table and attach a trigger that listens for UPSERTs. The trigger will put messages on the Postgres pubsub whenever the user sends a message or edits an old one.
First let’s create a migration for trigger. Let’s split the trigger into a function that prepares and sends the message to the Postgres pubsub queue. Use json_build_object
if you want to send extra data to your resolvers in Postgraphile. Since the Postgraphile resolvers have access to a pgSql client sometimes the topic alone is enough of them and they can gather the data by executing SQL queries themselves.
1CREATE OR REPLACE FUNCTION notify_messages_upserted() 2 RETURNS trigger AS $notify_messages_upserted$ 3BEGIN 4 PERFORM pg_notify( 5 -- topic name 6 'messages:upsert:' || NEW."object_id", 7 -- optional extra data 8 json_build_object( 9 'event', 'upsert', 10 'objectId', NEW."object_id" 11 -- just an example optional JSON object data 12 )::text); 13 RETURN NEW; 14END; 15$notify_messages_upserted$ LANGUAGE plpgsql;
Secondly create the trigger and attach it on the messages
table. It will run the function above on every UPSERT event.
1DROP TRIGGER IF EXISTS messages_upserted_trigger ON messages; 2CREATE TRIGGER messages_upserted_trigger 3 AFTER INSERT OR UPDATE ON messages 4 FOR EACH ROW 5EXECUTE PROCEDURE notify_messages_upserted();
There is no