Webhooks 101: Let the Server Notify You

Miguel MirandaMiguel Miranda
3 min read

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?

web-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

  1. Your app registers a webhook URL with the source system.
  2. When an event occurs (e.g., a payment), the source system sends a POST request to your webhook endpoint.
  3. 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

web-hooks


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

0
Subscribe to my newsletter

Read articles from Miguel Miranda directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Miguel Miranda
Miguel Miranda

Sharing Experiences and Insights.