Webhook vs API


Understanding the difference between webhooks and APIs is crucial for building efficient, real-time applications.

API (Application Programming Interface)

Definition: A request-response model where the client actively requests data from the server.

How APIs Work (Pull Model)
sequenceDiagram participant Client participant Server loop Every 5 minutes Client->>Server: GET /api/orders Server->>Client: Response (orders data) end
API Example (REST)
// Client makes request
GET https://api.example.com/users/123

// Server responds
{
  "id": 123,
  "name": "John Doe",
  "email": "john@example.com"
}

Webhook

Definition: An event-driven model where the server automatically sends data to the client when an event occurs.

How Webhooks Work (Push Model)
sequenceDiagram participant Server participant Client Note over Server: Event occurs (e.g., new order) Server->>Client: POST /webhook/orders Note over Server: Sends event data Client->>Server: 200 OK
Webhook Example
// Server sends POST request to client's webhook URL
POST https://your-app.com/webhook/payment

{
  "event": "payment.success",
  "payment_id": "pay_123",
  "amount": 99.99,
  "timestamp": "2024-01-15T10:30:00Z"
}

Key Differences

Aspect API Webhook
Model Pull (Request-Response) Push (Event-Driven)
Initiator Client Server
Timing On-demand Real-time (when event occurs)
Efficiency May poll unnecessarily Only sends when needed
Use Case Fetching data on demand Real-time notifications

Implementing a Webhook

Node.js Example
const express = require('express');
const app = express();

app.use(express.json());

// Webhook endpoint
app.post('/webhook/github', (req, res) => {
    const event = req.headers['x-github-event'];
    const payload = req.body;
    
    console.log(`Received ${event} event`);
    
    if (event === 'push') {
        console.log(`New push to ${payload.repository.name}`);
        console.log(`Commits: ${payload.commits.length}`);
    }
    
    res.status(200).send('Webhook received');
});

app.listen(3000, () => {
    console.log('Webhook server running on port 3000');
});
C# Example (ASP.NET Core)
[ApiController]
[Route("webhook")]
public class WebhookController : ControllerBase
{
    [HttpPost("stripe")]
    public IActionResult StripeWebhook()
    {
        var json = new StreamReader(HttpContext.Request.Body).ReadToEnd();
        var stripeEvent = EventUtility.ParseEvent(json);
        
        switch (stripeEvent.Type)
        {
            case "payment_intent.succeeded":
                var paymentIntent = stripeEvent.Data.Object as PaymentIntent;
                Console.WriteLine($"Payment succeeded: {paymentIntent.Id}");
                break;
                
            case "payment_intent.payment_failed":
                Console.WriteLine("Payment failed");
                break;
        }
        
        return Ok();
    }
}

Webhook Security

1. Signature Verification
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
    const expectedSignature = crypto
        .createHmac('sha256', secret)
        .update(payload)
        .digest('hex');
    
    return crypto.timingSafeEqual(
        Buffer.from(signature),
        Buffer.from(expectedSignature)
    );
}

// Usage
app.post('/webhook', (req, res) => {
    const signature = req.headers['x-webhook-signature'];
    const payload = JSON.stringify(req.body);
    
    if (!verifyWebhookSignature(payload, signature, SECRET)) {
        return res.status(401).send('Invalid signature');
    }
    
    // Process webhook
    res.status(200).send('OK');
});
2. IP Whitelisting
const allowedIPs = ['192.168.1.100', '10.0.0.50'];

app.post('/webhook', (req, res) => {
    const clientIP = req.ip;
    
    if (!allowedIPs.includes(clientIP)) {
        return res.status(403).send('Forbidden');
    }
    
    // Process webhook
    res.status(200).send('OK');
});
3. HTTPS Only

Real-World Examples

GitHub Webhooks
Stripe Webhooks
Twilio Webhooks

When to Use Each

Use APIs When:
Use Webhooks When:
Use Both Together
graph LR Client[Client App] API[REST API] Webhook[Webhook Endpoint] Server[Server] Client -->|GET /orders| API API -->|Response| Client Server -->|POST /webhook/new-order| Webhook Webhook -->|Notify| Client

Example: Use API to fetch initial data, then use webhooks to receive real-time updates.

Best Practices