PostgreSQL Meets the Web: Unleashing HTTP Triggers and API Calls Directly from Your Database
Share this article
For developers orchestrating complex data workflows, the boundary between database logic and external services often creates friction. Enter pgsql-http, a PostgreSQL extension that shatters this barrier by embedding HTTP client capabilities directly into the database engine. This tool transforms SQL from a data query language into a gateway for web interactions—enabling triggers that ping microservices, stored procedures that consume APIs, and real-time data enrichment without middleware.
Beyond Simple GET Requests
While basic HTTP GET functionality is table stakes, pgsql-http offers nuanced control:
-- Authenticated API call with headers
SELECT content::json->'headers'->>'Authorization'
FROM http(('GET', 'https://api.example.com',
http_headers('Authorization','Bearer token'),
NULL, NULL)::http_request);
Key features include:
- Full HTTP Method Support: GET, POST, PUT, PATCH, DELETE, and HEAD
- Structured Request/Response Objects: Native http_request and http_response composite types
- Header Management: Array-based http_header tuples for precise control
- Binary Payload Handling: text_to_bytea() for processing images, files, or protobufs
- Dynamic Parameterization: JSONB payloads for POST/PUT requests
The Architecture Underneath
Every operation revolves around two core composite types:
http_request (
method http_method,
uri VARCHAR,
headers http_header[],
content_type VARCHAR,
content VARCHAR
)
http_response (
status INTEGER,
content_type VARCHAR,
headers http_header[],
content VARCHAR
)
Convenience wrappers like http_get() or http_post() abstract these types, but power users can construct raw requests for advanced scenarios. Header arrays can be destructured with unnest(), allowing granular inspection of responses.
Production-Grade Configuration
Serious deployments require tuning:
-- Set connection timeout to 200ms
SET http.curlopt_timeout_msec = 200;
-- Enable TCP keep-alive for performance
SET http.curlopt_tcp_keepalive = 1;
-- Identify requests for abuse monitoring
SET http.curlopt_useragent = 'MyApp/1.0 (+http://myapp.com/contact)';
The extension exposes 30+ libcurl options, including proxies, TLS authentication, and DNS settings—configurable per connection, role, or database.
Why Proceed with Caution?
While compelling, database-triggered HTTP calls introduce risks:
"What if the web page takes a long time to return? Your SQL call will just wait there until it does. Make sure your web service fails fast."
— Extension documentation
Critical considerations:
1. Blocking Operations: HTTP calls execute synchronously, potentially freezing database sessions.
2. Error Handling: Malformed responses or timeouts require explicit SQL-side validation.
3. Security: Exposing HTTP in triggers could enable SSRF attacks or accidental DDoS.
4. Resource Consumption: Each request consumes connections; runaway triggers could exhaust sockets.
Mitigations include aggressive timeouts (set via curlopt_timeout_ms), using pg_cron for async execution, and strict function permission controls.
Practical Use Cases
When used judiciously, pgsql-http enables powerful patterns:
- Real-Time Enrichment: Augment user profiles via API on INSERT
- Webhook Triggers: Notify external systems on data changes
- Microservice Orchestration: Chain database operations with service calls in transactions
- Data Hydration: Pull external datasets directly into temp tables
Getting Started
For Debian-based systems:
apt install postgresql-17-http # Replace 17 with your PG version
Then in PostgreSQL:
CREATE EXTENSION http;
-- Test connectivity
SELECT status FROM http_get('https://httpbun.com');
The Delicate Power
pgsql-http exemplifies PostgreSQL's extensibility, turning the database into an active participant in distributed systems. Yet this power resembles a sharp knife: invaluable for precise tasks, dangerous when mishandled. Developers must weigh the convenience of in-database HTTP against PostgreSQL's core strengths—and remember that some boundaries exist for good reason. When APIs meet ACID, proceed with both ambition and humility.