Skip to content

πŸͺ Real-time webhook testing with per-key routing, expression-based rule engine, and configurable responses. Beautiful embedded UI, single binary, zero config

License

Notifications You must be signed in to change notification settings

essajiwa/hooklab

Repository files navigation

πŸ§ͺ Hooklab

Mock APIs. Test webhooks. Debug integrations.

Go Report Card Go Version codecov
Run Test License GitHub stars GitHub forks

Features β€’ Use Cases β€’ Quick Start β€’ API β€’ Contributing


The Problem

Testing integrations is painful:

  • ngrok setup for every webhook project
  • No visibility into what external services send
  • Hard to mock third-party API responses in tests
  • Context switching between terminal and browser

The Solution

A single binary server that captures webhooks AND mocks API responses. Zero config, instant feedback, beautiful UI.

Webhook Test Server UI


Features

Feature Description
πŸ”€ Per-key Routing /webhook/{key} β€” each key has independent response config
πŸ§ͺ Mock API Server Use as a mock server in unit/integration tests
⚑ Rule Engine Expression-based conditional responses (docs)
🎯 Real-time Updates SSE streaming, see requests as they arrive
🎨 Beautiful UI Embedded React + Tailwind, color-coded HTTP methods
πŸ”§ Configurable Responses Set status codes and JSON responses per endpoint
πŸ“¦ Single Binary No dependencies, just go run .

Quick Start

Requirements

  • Go 1.18 or later

Run

go run .

Open UI

http://localhost:8080

Send a Webhook

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"message":"hello"}' \
  http://localhost:8080/webhook

Use Custom Keys

Each key gets its own response configuration:

# Stripe webhooks
curl -X POST -d '{"type":"payment"}' http://localhost:8080/webhook/stripe

# GitHub webhooks  
curl -X POST -d '{"action":"push"}' http://localhost:8080/webhook/github

Use Cases

1. Webhook Testing

Capture and inspect incoming webhooks from external services:

# Point Stripe/GitHub/etc. to your Hooklab instance
curl -X POST -d '{"event":"payment.success"}' http://localhost:8080/webhook/stripe

2. Mock API Server

Use Hooklab as a mock server in your tests:

JavaScript/Jest:

// Configure mock response before test
await fetch('http://localhost:8080/api/response?key=payment-api', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    response: { id: 'ch_123', status: 'succeeded' },
    statusCode: 200
  })
});

// Your code calls the mock instead of real API
const result = await paymentService.charge({
  apiUrl: 'http://localhost:8080/webhook/payment-api'
});

expect(result.status).toBe('succeeded');

Go:

// Setup: configure Hooklab response
resp, _ := http.Post(
    "http://localhost:8080/api/response?key=external-api",
    "application/json",
    strings.NewReader(`{"response":{"success":true},"statusCode":200}`),
)

// Test: point your code to Hooklab
client := NewClient("http://localhost:8080/webhook/external-api")
result, err := client.DoSomething()
assert.True(t, result.Success)

3. Error Simulation

Test how your code handles failures:

# Configure 500 error response
curl -X POST http://localhost:8080/api/response?key=flaky-api \
  -H "Content-Type: application/json" \
  -d '{"response":{"error":"Internal Server Error"},"statusCode":500}'

# Your integration tests can now verify error handling

4. Rule Engine

Create conditional responses based on request data:

# Create a rule: return error for high-value transactions
curl -X POST "http://localhost:8080/api/rules?key=payments" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "High Value Alert",
    "condition": "body.amount > 1000",
    "response": {"status": "review_required"},
    "statusCode": 202,
    "priority": 1,
    "enabled": true
  }'

Rules are evaluated in priority order. First match wins. See RULES.md for full expression syntax.

πŸ“Έ Rule Engine Screenshots

Rules List Rules List

Rule Editor Rule Editor

5. CI/CD Integration

Run Hooklab in your CI pipeline:

# GitHub Actions example
services:
  hooklab:
    image: golang:1.21
    ports:
      - 8080:8080
    command: go run github.com/essajiwa/hooklab@latest

Configuration

Flag Description Default
-port HTTP server port 8080
-response Default JSON response {"result":"ok"}

API Endpoints

Method Endpoint Description
ANY /webhook or /webhook/{key} Capture webhook, return configured response
GET /api/events?key={key} List recent events (optional key filter)
GET /api/stream SSE stream of all events
GET /api/response?key={key} Get response config for a key
POST /api/response?key={key} Update response config { response, statusCode }
GET /api/rules?key={key} List rules for a webhook key
POST /api/rules?key={key} Create a new rule
PUT /api/rules?key={key}&id={id} Update an existing rule
DELETE /api/rules?key={key}&id={id} Delete a rule
GET /api/keys List all known webhook keys

Why This Over Alternatives?

Hooklab webhook.site ngrok
Self-hosted βœ… ❌ ❌
Per-key routing βœ… ❌ ❌
Custom responses βœ… Limited ❌
Rule engine βœ… ❌ ❌
Real-time UI βœ… βœ… ❌
Free & Open Source βœ… Freemium Freemium
Single binary βœ… N/A ❌

⚠️ Security Considerations

Hooklab is designed as a development and testing tool. Before deploying:

Concern Status Notes
Authentication ❌ None All endpoints are public by default
Request Size βœ… Limited Bodies capped at 1MB to prevent DoS
Data Exposure ⚠️ Caution Request headers (including auth tokens) are stored and displayed
Rate Limiting ❌ None No built-in rate limiting

Recommendations:

  • Do NOT expose to the public internet without a reverse proxy (nginx, Caddy) with authentication
  • Use behind a VPN or firewall for team access
  • Consider the systemd service with RuntimeMaxSec for periodic data reset
  • Sensitive headers (Authorization, Cookie, etc.) will be visible in the UI

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Look for issues labeled good first issue to get started.


Built With

Backend

  • Go β€” Fast, reliable backend
  • expr β€” Expression evaluation for rule engine

Frontend

Tools


License

MIT β€” see LICENSE.


⬆ Back to top

Made with ❀️ by @essajiwa

About

πŸͺ Real-time webhook testing with per-key routing, expression-based rule engine, and configurable responses. Beautiful embedded UI, single binary, zero config

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published