Need webhooks? Just use the Postgres HTTP extension
Reducing complexity
I previously wrote a blog about using pg_notify and a Golang listener to create a webhook based on Postgres events.
I no longer believe this is the best approach, after trying out the pgsql-http extension for this use case.
The http extension is super simple:
- Ensure the extension is installed and enabled.
- Create an SQL trigger for an event in your database.
- Call a function from your trigger that does a http call (GET, POST, etc possible).
- You can send a payload to an external webhook, including
DB data, and even an
X-API-Keyheader 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/*
-
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 image here
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);
- I was adding this to an existing database schema for ODK Central, so instead opted to build a small Golang CLI for installing and uninstalling the trigger, based on certain events.
For the example implementation, see this repo
- ← Previous
The field mapping phoenix