Skip to content

feat: move the API to a Cloudflare Worker and drop the Swift Lambda - #74

Merged
bradwindy merged 3 commits into
mainfrom
feat-cloudflare-worker-api
Oct 24, 2026
Merged

bradwindy merged 3 commits into
mainfrom
feat-cloudflare-worker-api

Conversation

@bradwindy

Copy link
Copy Markdown
Owner

Part 2 of moving NZ Images to the Cloudflare Free plan, with a free-tier AWS converter. Part 1 was #73.

What changes

  • worker/ is nzimages-api, a TypeScript port of the Swift Lambda on the Workers Free plan. It is already deployed at https://nzimages-api.iolab.nz.
    • Same responses, secret-header auth, DigitalNZ pattern, strategy registry and converter signing. On 94 live records from 47 collections, the Swift and Worker outputs were identical.
    • ImageApi RPC entrypoint for the website's service binding.
    • src/http.ts follows redirects itself and caps each request at 50 subrequests (the Free plan limit).
  • 125 Vitest tests in workerd port the Swift suite. check-collections and count-collections replace CollectionTester and CollectionLister.
  • template.yaml keeps only the converter, its kill switch, the spike alarm, the cost topic and the budget. The Swift Lambda, HTTP API and API alarm are removed, along with all Swift sources, tests and build scripts.
  • CI: Worker typecheck, tests and a bundle dry-run. The deploy job deploys only the converter stack, and Workers Builds deploys the Worker.
  • collection-reviewer-web boots the Worker with wrangler dev instead of the Swift Lambda. Docs rewritten.

Live checks on the deployed Worker

  • check-collections against the live Worker, comparing with the Lambda: 45/48 pass. The 3 failures are bugs carried over from Swift unchanged:
    • V&A URLs 404.
    • Portrait Gallery has 0 records.
    • Waikato fails on some random records, on the Lambda too.
  • CPU time: median 3.3 ms, max 8 ms across 96 requests, plus one 11 ms reading that still succeeded. The Free plan allows 10 ms.
  • scripts/smoke-test-access-control.sh --throttle: 200 with the secret, 401 without, and 429 from the iolab.nz WAF rule.
  • The website (nzimage-web#74) is live on Cloudflare and calls this over RPC, including converted TAPUHI images.

Merging deletes the Swift Lambda and API Gateway. Nothing calls them any more, since the website moved to RPC.

🤖 Generated with Claude Code

bradwindy and others added 3 commits October 24, 2026 18:39
- worker/: nzimages-api, a TypeScript port of the Swift Lambda for the
  Workers Free plan (custom domain nzimages-api.iolab.nz). Same /image and
  /collections responses, secret-header auth, DigitalNZ two-request pattern,
  strategy registry and converter signing, verified identical on 94 live
  records. Adds an ImageApi RPC entrypoint for the website's service binding
  and keeps every request under the Free plan's 50 subrequests.
- 125 Vitest tests in workerd port the Swift suite. check-collections and
  count-collections replace CollectionTester and CollectionLister.
- template.yaml now holds only the converter, its kill switch, the spike
  alarm, the cost topic and the budget. The Swift Lambda, HTTP API and API
  alarm are removed, as are the Swift sources, tests and build scripts.
- CI runs the Worker's typecheck, tests and a bundle dry-run, and deploys
  only the converter stack. Workers Builds deploys the Worker.
- collection-reviewer-web boots the Worker with wrangler dev instead of the
  Swift Lambda. Docs rewritten for the new layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Drop the DigitalNZ key when a redirect leaves its origin.
- Escape ids taken from URL paths before building patterns.
- Accept an HTTP-style comma string for the RPC exclude list.
- Strip unclosed comments/scripts in one linear pass, so a malformed page
  can't blow the 10 ms CPU budget.
- Reviewer dev script: pass wrangler only DIGITALNZ_API_KEY through a temp
  env file, signal its process group so workerd doesn't outlive it, and use
  port 8977 instead of wrangler's default 8787.
- local_server.py defaults to 8788 with Worker instructions. Empty
  CONVERTER_SIGNING_KEY in .dev.vars.example. ADR 0001 notes the hosting
  move. renovate.json keeps its original formatting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- RPC image() accepts null options, and the comma-string exclude drops
  empty pieces like the HTTP path.
- tooManyRedirects reports the hop where it stopped.
- check-collections sniffs file type from the first chunk instead of
  downloading whole converted images.
- Reviewer dev script passes its three Worker values as --var flags, which
  beat worker/.dev.vars and the environment, and cleans up on a crash.
- CI fails the deploy if the converter's Function URL no longer matches
  JP2_CONVERTER_URL in worker/wrangler.jsonc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bradwindy
bradwindy merged commit ffb9787 into main Oct 24, 2026
3 checks passed
@bradwindy
bradwindy deleted the feat-cloudflare-worker-api branch October 24, 2026 06:05
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