Status: Accepted
Date: 2026-04-22
Branch / PR: aggregation/http-transport
Depends on: ADR 028
HttpServerTransport has to integrate with many HTTP framework choices that a service operator might prefer: Hono, Express, Fastify, Bun’s native server, Cloudflare Workers, Deno Deploy, AWS Lambda, etc. Each has different primitives for:
The codebase also has a standing constraint: all code must be browser-compatible; no Node.js-only APIs. This precludes bundling node:http as an internal dependency even for the server side: server deployments might run in Workers or Deno.
Existing precedent in the repo for I/O-agnostic patterns:
bitcoin/src/connection.ts uses an injected HttpExecutor so the Bitcoin RPC layer stays pure.Resolver and Updater state machines are sans-I/O and emit typed DataNeed requests (see ADR 016).node:http internally. Node-only; violates browser-compat constraint and locks out Workers/Deno deployments.@did-btcr2/method/transport/http/express, @did-btcr2/method/transport/http/hono, etc. Multiple adapters to maintain, and new frameworks need us to add support.fetch-style handler. The server is a (Request) => Promise<Response> function. Idiomatic in Workers / Deno; awkward for Express.handleRequest / handleSse primitives over framework-agnostic HttpRequestLike / HttpResponseLike / SseStream types.Option 4. HttpServerTransport exposes two methods:
handleRequest(req: HttpRequestLike): Promise<HttpResponseLike>;
handleSse(req: HttpRequestLike, stream: SseStream): void;
The caller writes ~15–30 lines of framework-specific glue to convert their framework’s request/response/stream primitives into and out of these shapes. The transport has zero direct I/O dependencies.
HttpRequestLike is a plain structural type: { method, url, headers, body?, remoteAddr? }. HttpResponseLike is { status, headers, body }. SseStream has writeEvent, writeComment, close, onClose.
Positive
handleRequest directly: no HTTP server needed, making tests both faster and more deterministic.fetchImpl to the server’s handlers in-process, proving end-to-end wire correctness without a real network.Negative
SseStream.writeEvent is synchronous from its perspective; adapters implementing it over Hono streams need to handle their framework’s write-signalling.Explicitly accepted trade-offs
http-transport.md as a starting point, or the node:http adapter demonstrated in lib/operations/aggregation/e2e-http-transport.ts.packages/method/src/core/aggregation/transport/http/server.ts: HttpServerTransport, HttpRequestLike, HttpResponseLike, SseStream.packages/method/docs/http-transport.md: Hono mount example.packages/method/lib/operations/aggregation/e2e-http-transport.ts: node:http adapter + full protocol run.packages/bitcoin/src/connection.ts: precedent for injected HttpExecutor pattern.