1. The Problem: "Are we there yet?" (Polling explained)
Last week, I was implementing authentication in a project and got stuck at a point where I couldn't save a newly logged-in user. So, I tried something that isn't considered a good practice in development: I implemented a polling system that runs every ten seconds.
What is Polling?
Polling is when your app keeps asking an API:
"Do you have anything new for me?"
The problems with this are:
- Unnecessary network traffic.
- Wasted server resources.
- Delays in reacting to actual changes.
- Not great for optimization.
2. A Better Alternative: Webhooks (Event-driven communication)
Now imagine instead of asking over and over, the server tells you the moment something happens.
Thatโs exactly what Webhooks do.
How Webhooks Work
- Your app registers a webhook URL with the source system.
- When an event occurs (e.g., a payment), the source system sends a
POST
request to your webhook endpoint. - Your system processes the event immediately โ no delays, no questions asked.
Think of it like receiving a push notification, instead of constantly refreshing the page.
๐๏ธ Real-world example (eCommerce):
You can use webhooks to get notified when:
- A customer completes a purchase
- A cart is abandoned
- Inventory is updated
3. Webhook Example in TypeScript (Next.js App Router)
Here's a simple and functional webhook endpoint using TypeScript with Next.js 13+ (App Router). This code handles incoming events like user.created
and user.deleted
from an external service (like Clerk or Stripe).
๐ File: /app/api/webhook/route.ts
import { NextRequest, NextResponse } from 'next/server';
// This function handles POST requests coming to /api/webhook
export async function POST(req: NextRequest) {
try {
// Parse the incoming JSON payload
const body = await req.json();
// Extract the event type and the actual data
const eventType = body.event;
const userData = body.data;
// Log the event for debugging purposes
console.log(`Received event: ${eventType}`, userData);
// Handle different event types based on your provider (e.g. Clerk, Stripe)
switch (eventType) {
case 'user.created':
// Save the new user to your database or take any other action
console.log('Saving new user:', userData);
break;
case 'user.deleted':
// Remove the user from your database
console.log('Deleting user:', userData);
break;
default:
// Log unhandled events for further inspection
console.warn('Unhandled event type:', eventType);
}
// Return a success response
return NextResponse.json({ message: 'Webhook received' }, { status: 200 });
} catch (error) {
// Catch any errors that occur during processing
console.error('Error handling webhook:', error);
return NextResponse.json({ error: 'Invalid request' }, { status: 400 });
}
}
It's pretty easy to implement. This is what happens after the webhook sends information to the registered URL when an event occurs in the external service.
4. Why It Matters
- Efficiency: No need for repetitive API calls.
- Real-time updates: React as soon as something happens.
- Scalability: Reduce load and improve performance.
Webhooks let systems communicate only when it matters, not every few seconds.
Conclusion
If you're building systems that need to react to changes from external sources, Webhooks are the modern, scalable way to do it.
Theyโre simple, fast, and extremely useful in today's event-driven world.
๐ If you found this article interesting or want to get in touch, Iโm active on X @mirchezz
Top comments (4)
Very nice! One of the reason we've built Kiponos.io. We use WebSockets internally and provide you a simple SDK so you benefit bi-directional permanent connection between all your servers and clients. I think you'll like it.
You can get our free plan if you're a single dev or managing a small team. Check it out..
This is such a clear breakdown of why webhooks are a game changer for efficiency, and the TypeScript example is super handy. Have you had to deal with securing your webhooks or handling failed deliveries yet?
Thanks!, To secure WorkOS, I send the payload with a signature and verify it on arrival, but generally if you work with external service they provide some sdk for verification. For failed deliveries, I usually set up polling as a fallback. And when there are lots of requests, I handle them with queues if needed.