Skip to content

feat: add request bins for inspecting captured HTTP requests#150

Merged
jaredwray merged 4 commits into
mainfrom
claude/add-request-bin-feature-xGmb1
May 19, 2026
Merged

feat: add request bins for inspecting captured HTTP requests#150
jaredwray merged 4 commits into
mainfrom
claude/add-request-bin-feature-xGmb1

Conversation

@jaredwray

Copy link
Copy Markdown
Owner

Summary

Adds requestbin.net-style request bins to mockhttp. Users mint an ephemeral URL, send arbitrary HTTP requests to it (any method, sub-path, or body), and read back what was received — useful for webhook debugging.

  • Management API under /bins/* — create, list, get, delete bins; list/get/clear captured requests
  • Capture endpoint at /b/:id and /b/:id/* records method, headers, query, body (utf8 for text, base64 for binary), IP, content-type, size, and a truncation flag
  • BinManager with a pluggable BinStore interface (InMemoryBinStore is the default — Redis/SQLite can plug in later without breaking changes). Configurable TTL (24h default), per-bin request cap (100, FIFO drop), and body size cap (1 MiB, truncate + flag).
  • Cleanup timer is unref()'d and stopped on server close() so it can never keep the Node process alive.
  • rewriteUrl now treats wildcard routes that also have non-wildcard params (like /b/:id/*) as specific, so subpath captures don't get rewritten away. Pure catch-all /* routes still defer to more specific prefix matches (existing behavior preserved).

Endpoints

Method Path Description
POST /bins Create a new bin
GET /bins List active bins
GET /bins/:id Get bin metadata
GET /bins/:id/requests List captured requests (newest first)
GET /bins/:id/requests/:reqId Get a single captured request
DELETE /bins/:id/requests Clear all captured requests in a bin
DELETE /bins/:id Delete a bin
ANY /b/:id and /b/:id/* Capture any request sent to a bin

Quick example

ID=$(curl -s -X POST http://localhost:3000/bins | jq -r .id)
curl -X POST "http://localhost:3000/b/$ID/webhook?source=stripe" \
  -H 'content-type: application/json' \
  -d '{"event":"payment.succeeded"}'
curl http://localhost:3000/bins/$ID/requests | jq

Test plan

  • pnpm test — 463 tests pass, lint clean
  • New files have 100% coverage; overall coverage unchanged from baseline (99.73%)
  • Smoke-tested via curl: bin create, JSON POST capture, binary PUT capture (round-trips through base64), HEAD capture, sub-path + query capture, list, get single, delete bin → 404
  • Swagger UI at /docs shows the new Bins tag with all seven management endpoints plus the capture route
  • Existing rewriteUrl test "prefers a specific route over a wildcard catch-all" still passes — pure /* fallback semantics preserved

Generated by Claude Code

Adds RequestBin-style endpoints so users can mint an ephemeral URL,
send arbitrary HTTP requests to it (any method, subpath, or body), and
read back what was received. Useful for webhook debugging.

- Management API at /bins: create, list, get, delete bins; list/get/clear
  captured requests
- Capture endpoint at /b/:id and /b/:id/* records method, headers,
  query, body (utf8 or base64 for binary), IP, content-type, size, and
  truncation flag
- BinManager with a pluggable BinStore interface (InMemoryBinStore is
  the default); configurable TTL (24h default), per-bin request cap
  (100, FIFO drop), and body size cap (1 MiB, truncate + flag)
- Cleanup timer is unref'd and stopped on server close
- rewriteUrl now treats wildcard routes with non-wildcard params (like
  /b/:id/*) as specific, so subpath captures don't get rewritten away
Comment thread src/routes/bins/capture.ts
@codecov

codecov Bot commented May 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (6524834) to head (02ef71f).

Additional details and impacted files
@@            Coverage Diff             @@
##              main      #150    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files           37        41     +4     
  Lines         1089      1310   +221     
  Branches       222       259    +37     
==========================================
+ Hits          1089      1310   +221     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements Request Bins, allowing users to capture and inspect incoming HTTP requests through ephemeral URL endpoints. The update includes a BinManager for lifecycle operations, a pluggable storage system with an in-memory default, and new Fastify routes for management and request capture. Review feedback highlighted the need for robust input validation in the BinManager constructor and defensive loop conditions in the storage layer to prevent potential runtime issues with negative configuration values.

Comment thread src/bin-store.ts Outdated
Comment thread src/bin-manager.ts
claude and others added 3 commits May 18, 2026 22:57
…estsPerBin

- Clamp BinManager maxRequestsPerBin to >= 0 so a misconfigured negative
  cap can't drive InMemoryBinStore.addRequest into a runaway pop loop
- Add defensive list.length > 0 guard in addRequest's eviction loop
- Add tests for the MockHttp.bins getter/setter, route registration with
  and without the bins flag, registerBinRoutes with an explicit fastify
  instance, and that close() stops the cleanup timer (lines codecov
  flagged as uncovered)
…ference

- Walk through a full webhook-debugging flow using curl
- Show body encoding in three modes: utf8, base64 (binary), and
  truncated, each with concrete examples
- Demonstrate FIFO eviction past maxRequestsPerBin
- Add a Vitest example using mock.bins programmatically in a test suite
- Sketch a Redis-backed BinStore implementation for the pluggable
  storage section
- List bins on the Features bullet list and Table of Contents
- Document bins.* methods, registerBinRoutes(), and the bins property
  in the API Reference
@jaredwray jaredwray merged commit 01cc106 into main May 19, 2026
9 checks passed
@jaredwray jaredwray deleted the claude/add-request-bin-feature-xGmb1 branch May 19, 2026 00:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants