Webhooks transform how applications communicate. Instead of repeatedly asking for updates, your application receives notifications when events occur. This event-driven approach is more efficient than traditional polling.
Understanding Webhooks
A webhook is an HTTP callback. When something happens in one system, it sends an HTTP POST request to a URL you specify. This URL belongs to your application, waiting to receive and process the notification.
The key difference from polling: the server pushes updates to you. You don't need to keep asking "has anything changed?" Instead, the server tells you "something changed."
This is like getting a phone call instead of calling someone repeatedly to ask if they have news. The communication is instantaneous and efficient.
How Webhooks Work
The webhook flow follows a simple pattern:
- You register a webhook URL with the service
- The service stores your URL and associates it with your account
- When an event occurs, the service POSTs data to your URL
- Your application receives the webhook and processes it
For example, with the Pet Store API, you might register for order notifications:
Your webhook URL: https://yourapp.com/webhooks/orders
When someone places an order, the API sends:
POST /webhooks/orders
Content-Type: application/json
{
"event": "order.created",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"id": 12345,
"customer": "john@example.com",
"total": 59.99,
"items": [
{"product": "Dog Food", "quantity": 2}
]
}
}
Your server receives this and processes the order automatically.
Webhooks vs Polling
The difference is dramatic. Let's compare the two approaches.
Polling:
// Check for new orders every 30 seconds
setInterval(async () => {
const response = await fetch('https://api.petstoreapi.com/v1/orders?since=' + lastCheck, {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const orders = await response.json();
for (const order of orders) {
processOrder(order);
}
lastCheck = Date.now();
}, 30000);
This approach wastes resources. Your server makes requests constantly, even when nothing happens. Network traffic increases unnecessarily. You need complex logic to track what you've already processed.
Webhooks:
// Receive webhook notification
app.post('/webhooks/orders', (req, res) => {
const order = req.body.data;
// Process immediately
processOrder(order);
res.status(200).send('OK');
});
This approach is efficient. You receive notifications only when events occur. No wasted requests. No polling logic. Immediate processing.
Setting Up Webhooks
Implement webhook handling in your application:
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
// Verify webhook signature
function verifySignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// Handle webhook
app.post('/webhooks/petstore', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const rawBody = JSON.stringify(req.body);
// Verify the request came from Pet Store API
if (!verifySignature(rawBody, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = req.body;
switch (event.event) {
case 'order.created':
handleNewOrder(event.data);
break;
case 'order.updated':
handleOrderUpdate(event.data);
break;
case 'order.shipped':
handleOrderShipped(event.data);
break;
case 'inventory.low':
handleLowInventory(event.data);
break;
}
res.status(200).send('Received');
});
Always verify webhook signatures. This ensures requests actually come from the service, not from attackers spoofing requests.
Registering Webhooks
Register your webhook URL with the Pet Store API. The exact process varies by service.
Typically, you configure webhooks through the dashboard or API:
curl -X POST "https://api.petstoreapi.com/v1/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/petstore",
"events": ["order.created", "order.updated", "inventory.low"]
}'
The service confirms registration and sends a test event. Verify your endpoint receives it.
Handling Failures
Webhooks can fail. Your server might be down. Network issues can occur. Handle these scenarios.
Return status codes quickly: Process webhooks asynchronously. Return 200 immediately, then process the actual data.
app.post('/webhooks/petstore', async (req, res) => {
res.status(200).send('OK'); // Return immediately
// Process in background
try {
await processWebhook(req.body);
} catch (error) {
console.error('Webhook processing failed:', error);
// Implement retry logic
}
});
Implement idempotency: The same webhook might arrive multiple times. Use event IDs to detect duplicates:
const processedEvents = new Set();
app.post('/webhooks/petstore', (req, res) => {
const eventId = req.body.eventId;
if (processedEvents.has(eventId)) {
return res.status(200).send('Already processed');
}
processedEvents.add(eventId);
// Process the event
});
Handle retries: Services typically retry failed webhooks. Your endpoint should handle these gracefully.
Webhook Security
Webhooks expose public endpoints. Protect them carefully.
Verify signatures: Every service provides a signature. Verify it.
Use HTTPS: Encrypt all webhook traffic.
Limit IP addresses: If possible, configure your firewall to accept requests only from service IP ranges.
Implement rate limiting: Prevent abuse by rate limiting requests.
Log all requests: Keep records for debugging and auditing.
Common Webhook Events
The Pet Store API supports various webhook events:
| Event | Description |
|---|---|
order.created |
New order placed |
order.updated |
Order details changed |
order.shipped |
Order marked as shipped |
order.completed |
Order finished |
order.cancelled |
Order cancelled |
inventory.low |
Stock below threshold |
inventory.updated |
Inventory count changed |
customer.registered |
New customer signup |
Subscribe to events relevant to your application.
Pet Store API Webhooks
Configure webhooks in the Pet Store API dashboard or through the API. Point to your endpoint that handles POST requests.
The documentation at docs.petstoreapi.com shows all available events, payload formats, and signature verification methods.
Webhooks simplify integration significantly. Instead of polling for changes, your application receives updates instantly. The event-driven approach scales better and reduces latency.