Docs / Batteries
Webhooks, queues & crons
React to data changes with durable, transactional delivery; receive verified inbound webhooks; send signed outgoing webhooks; run scheduled jobs — on Cloudflare, AWS or plain Postgres transports.
CRUD is rarely the whole job. Something has to fire when an order is paid, receive the Stripe webhook, and run the nightly cleanup — and it’s exactly the code that silently drops events when it’s hand-rolled. gqlith generates an integration fabric for it, governed like everything else, and inert until you use it.
React to changes — with a durability tier you choose
on("orders.update", handler, {
deliver: "durable",
idempotency: (e) => `orderPaid:${e.id}`,
});
durable— the event is written to a delivery outbox inside the same transaction as the change. If the row committed, the event exists; if the mutation rolled back, it never happened. Delivery drains at-least-once with retries, a dead-letter queue, and idempotency-keyed dedup for exactly-once effect.bestEffort— runs after commit via the deferred-work seam; right for cache pokes and notifications where a rare miss is fine.
Handlers run on a service context: a request-less identity that is audited as actorType: "service" and goes through the same governed data path — an event handler can’t accidentally bypass tenancy or RLS.
Verified inbound webhooks
inbound({ source: "stripe", verify, parse, handler });
Inbound endpoints mount at /ingress/<name> with signature verification in front of your handler and uniform fail responses — probing the endpoint doesn’t reveal whether a source exists. Queue-backed sources route the same way.
Signed outgoing webhooks
ctx.deliverWebhook({ url, secret }, payload) sends HMAC-signed webhooks over the durable tier, with per-key ordering, filtering and payload projection — consumers see events in order, per entity, shaped how you declared. Signing uses the GQLITH_WEBHOOK_SIGNING_KEY environment variable; delivery behavior (attempts, backoff, per-cycle budget, retention) is tuned in the deliveryPolicy config block.
Scheduled jobs
Cron-style scheduled triggers generate to native primitives per runtime — Cloudflare [triggers] crons on Workers, Deno.cron on Deno, and a dev-mode interval locally. gqlith’s own storage reaper runs on this.
Portable transports
Delivery and ingress are adapter slots like everything else: Cloudflare Queues and Durable Object alarms on Workers, SQS on AWS (both directions), and pg-poll — a plain-Postgres durable relay that needs no queue infrastructure at all. Swap by config, not by rewrite.
External extensions get the same surface: a build-time @gqlith/sdk exposes on(), inbound() and deliverWebhook() to extension packages declared in the extensions config array (file:, npm: or git+ specs), with per-extension settings under extensionConfig.