DEV Community

Sam
Sam

Posted on • Originally published at spwoodcock.dev on

Need webhooks? Just use the Postgres HTTP extension

Reducing complexity

I previously wrote a blog aboutusing pg_notify and a Golang listenerto create a webhook based on Postgres events.

I no longer believe this is the best approach, after trying out thepgsql-http extensionfor this use case.

The http extension is super simple:

  1. Ensure the extension is installed and enabled.
  2. Create an SQL trigger for an event in your database.
  3. Call a function from your trigger that does a http call (GET, POST, etc possible).
  4. You can send a payload to an external webhook, including DB data, and even an X-API-Key header for authentication (or whatever you use in your API).

Now we no longer need an external service / listener running to wait for the events. Everything can be handled entirely in Postgres (a pattern that I am really loving recently, from cron jobs, webhooks, ML embeddings, etc).

How this works in practice

Adding the extension

  • A custom dockerfile is very simple:
FROM postgres:18 AS pg-18

RUN apt-get update \
    && apt-get install -y postgresql-18-http \
    && rm -rf /var/lib/apt/lists/*
Enter fullscreen mode Exit fullscreen mode



  • You can use the same logic to add the extension to a Debian server install.

  • I actually build and publish pre-built images based on this exact logic - simply adding the extension into the official imagehere

For example: docker pull ghcr.io/hotosm/postgres:17-http

Adding a database trigger

  • If you manage you own database schema, you can add functions and triggers to your hearts content. Just add a http_request.
PERFORM http((
    'POST',
    'https://some.url.com/endpoint',
    http_headers('Content-Type', 'application/json'),
    'application/json',
    webhook_payload::text
)::http_request);
Enter fullscreen mode Exit fullscreen mode



  • I was adding this to an existing database schema forODK Central, so instead opted to build a small Golang CLI for installing and uninstalling the trigger, based on certain events.

For the example implementation, seethis repo

Top comments (0)