Skip to content

feat!: use Fetch API for HTTP transport - #654

Open
kahirokunn wants to merge 5 commits into
cloudevents:mainfrom
kahirokunn:http-transport-fetch
Open

feat!: use Fetch API for HTTP transport#654
kahirokunn wants to merge 5 commits into
cloudevents:mainfrom
kahirokunn:http-transport-fetch

Conversation

@kahirokunn

@kahirokunn kahirokunn commented Aug 17, 2026

Copy link
Copy Markdown

Fixes: #564
Fixes: #534

Proposed Changes

Use the Fetch API for the built-in HTTP transport, add opt-in retries with withRetry(), and add configurable emitter timeouts with withTimeout().

Description

httpTransport() now resolves successful sends with the native Fetch Response and the handled body. Non-2xx responses, aborts, and network failures reject with HTTPTransportError. The transport accepts Fetch headers and options, response handlers, and transport-wide or per-send abort signals. Redirects fail by default unless enabled with fetchOptions.redirect.

withRetry() retries common temporary HTTP failures with capped randomized exponential backoff and honors Retry-After for 429 and 503 responses. Every attempt sends the same CloudEvent, so receivers should handle duplicates.

withTimeout() gives each emitter invocation a configurable deadline and combines it with a caller-provided abort signal. When composed inside withRetry(), each attempt receives a fresh timeout; when composed outside it, one timeout covers every attempt and retry backoff. Timed-out HTTP sends reject with an HTTPTransportError whose kind is aborted, and the default retry policy does not retry them.

See API_TRANSITION_GUIDE.md for the breaking changes and migration examples.

@kahirokunn
kahirokunn force-pushed the http-transport-fetch branch 2 times, most recently from 92f1278 to 8077cd8 Compare August 17, 2026 16:15
@kahirokunn

Copy link
Copy Markdown
Author

@lholmquist Hi ✋ would you mind taking a look when you have a chance? Thank you 🙏

Signed-off-by: kahirokunn <okinakahiro@gmail.com>
Signed-off-by: kahirokunn <okinakahiro@gmail.com>
BREAKING CHANGE: httpTransport() is built on the Fetch API, which changes
what it resolves with, what it sends, and what it needs from its environment.

- A response that is not 2xx rejects with an HTTPTransportError instead of
  resolving, so a receiver which refused an event no longer looks like one
  that accepted it. Its kind tells a bad status from an abort and from a
  request that never reached a response
- A send resolves with { response, body } rather than { body, headers }.
  response is the native Fetch Response, so its headers are a Fetch Headers
  instance and not Node's IncomingHttpHeaders
- Redirects are no longer followed. fetchOptions: { redirect: "follow" }
  restores that, keeping in mind that Fetch preserves the CloudEvent POST
  and its body only for 307 and 308
- Options declares headers and signal, which used to fall under an index
  signature that resolved to unknown, so TypeScript now checks them
- Proxies and custom CAs set on http.globalAgent no longer apply, since
  Fetch does not use those agents. On Node.js an undici dispatcher passed
  through fetchOptions is the equivalent

See API_TRANSITION_GUIDE.md for the migration steps.

Signed-off-by: kahirokunn <okinakahiro@gmail.com>
Signed-off-by: kahirokunn <okinakahiro@gmail.com>
Signed-off-by: kahirokunn <okinakahiro@gmail.com>
@kahirokunn
kahirokunn force-pushed the http-transport-fetch branch from ca4e0fd to da9ed1a Compare August 18, 2026 14:38
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.

Add support for request timeout in HTTP transport Can't resolve 'http' error when using on React app

1 participant