Skip to content

fix(openapi): use Workers-native fetch for spec URLs#270

Merged
RhysSullivan merged 1 commit intomainfrom
rs/openapi-workers-fetch
Apr 17, 2026
Merged

fix(openapi): use Workers-native fetch for spec URLs#270
RhysSullivan merged 1 commit intomainfrom
rs/openapi-workers-fetch

Conversation

@RhysSullivan
Copy link
Copy Markdown
Owner

Adding an OpenAPI source via URL hangs on production Cloudflare Workers.
Two compounding causes:

  1. @apidevtools/swagger-parser fetches URLs via @apidevtools/json-schema-ref-parser's
    HTTP resolver, which goes through Node's http/https under nodejs_compat and
    stalls indefinitely on prod workerd. It also inlines every $ref on bundle(),
    deep-cloning shared schemas — a 16MB spec balloons to hundreds of MB and
    trips the 128MB Worker cap before it can finish.

  2. addSpec wrapped parse + extract inside ctx.transaction, so the pool=1
    Hyperdrive Postgres connection held BEGIN open across the network fetch.

Changes:

  • parse.ts: drop @apidevtools/swagger-parser entirely. Add fetchSpecText(url)
    that uses @effect/platform's HttpClient with a 20s Effect.timeout — pluggable
    via FetchHttpClient.layer (Workers-native) or a test-injected fetch. parse()
    is now JSON.parse + YAML fallback + 3.x validation; no ref resolution, because
    DocResolver (openapi-utils.ts) already resolves $refs lazily and
    normalizeOpenApiRefs preserves them through to the $defs table. Removed the
    manual resolveRefsInPlace walker — same deep-clone memory problem.

  • plugin.ts: resolveSpecText(config.spec) runs with httpClientLayer provided;
    parse + extract run BEFORE ctx.transaction. Only the three storage writes
    (upsertSource, sources.register, definitions.register) stay inside the tx,
    so Hyperdrive's single connection isn't held during network I/O. detect() +
    previewSpec() get the same treatment.

  • preview.ts / preview-oauth2.test.ts / real-specs.test.ts: wrap previewSpec
    with FetchHttpClient.layer where tests call it directly. real-specs.test.ts
    also strips the three in-memory-adapter addSpec tests — equivalent coverage
    lives in the cloud-app integration suite after this stack lands.

  • package.json / bun.lock: drop @apidevtools/swagger-parser.

openapi test suite: 30/30 pass, 2.4s (was 12.4s with swagger-parser).

Adding an OpenAPI source via URL hangs on production Cloudflare Workers.
Two compounding causes:

1. @apidevtools/swagger-parser fetches URLs via @apidevtools/json-schema-ref-parser's
   HTTP resolver, which goes through Node's http/https under nodejs_compat and
   stalls indefinitely on prod workerd. It also inlines every $ref on bundle(),
   deep-cloning shared schemas — a 16MB spec balloons to hundreds of MB and
   trips the 128MB Worker cap before it can finish.

2. addSpec wrapped parse + extract inside ctx.transaction, so the pool=1
   Hyperdrive Postgres connection held BEGIN open across the network fetch.

Changes:

- parse.ts: drop @apidevtools/swagger-parser entirely. Add fetchSpecText(url)
  that uses @effect/platform's HttpClient with a 20s Effect.timeout — pluggable
  via FetchHttpClient.layer (Workers-native) or a test-injected fetch. parse()
  is now JSON.parse + YAML fallback + 3.x validation; no ref resolution, because
  DocResolver (openapi-utils.ts) already resolves $refs lazily and
  normalizeOpenApiRefs preserves them through to the $defs table. Removed the
  manual resolveRefsInPlace walker — same deep-clone memory problem.

- plugin.ts: resolveSpecText(config.spec) runs with httpClientLayer provided;
  parse + extract run BEFORE ctx.transaction. Only the three storage writes
  (upsertSource, sources.register, definitions.register) stay inside the tx,
  so Hyperdrive's single connection isn't held during network I/O. detect() +
  previewSpec() get the same treatment.

- preview.ts / preview-oauth2.test.ts / real-specs.test.ts: wrap previewSpec
  with FetchHttpClient.layer where tests call it directly. real-specs.test.ts
  also strips the three in-memory-adapter addSpec tests — equivalent coverage
  lives in the cloud-app integration suite after this stack lands.

- package.json / bun.lock: drop @apidevtools/swagger-parser.

openapi test suite: 30/30 pass, 2.4s (was 12.4s with swagger-parser).
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 17, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing bdbb8e6 Commit Preview URL

Branch Preview URL
Apr 17 2026, 06:59 PM

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 17, 2026

Open in StackBlitz

@executor/sdk

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/sdk@270

@executor/plugin-file-secrets

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-file-secrets@270

@executor/plugin-google-discovery

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-google-discovery@270

@executor/plugin-graphql

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-graphql@270

@executor/plugin-keychain

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-keychain@270

@executor/plugin-mcp

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-mcp@270

@executor/plugin-oauth2

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-oauth2@270

@executor/plugin-onepassword

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-onepassword@270

@executor/plugin-openapi

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-openapi@270

@executor/plugin-workos-vault

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-workos-vault@270

executor

npm i https://pkg.pr.new/RhysSullivan/executor@270

commit: bdbb8e6

@RhysSullivan RhysSullivan merged commit bee25da into main Apr 17, 2026
9 checks passed
@RhysSullivan RhysSullivan deleted the rs/openapi-workers-fetch branch April 17, 2026 19:02
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.

1 participant