Skip to content

edge functions example for redirect maps on edge delivery#2

Open
krystiannowak wants to merge 1 commit into
adobe:mainfrom
krystiannowak:edge-delivery-redirect-maps
Open

edge functions example for redirect maps on edge delivery#2
krystiannowak wants to merge 1 commit into
adobe:mainfrom
krystiannowak:edge-delivery-redirect-maps

Conversation

@krystiannowak

Copy link
Copy Markdown
Collaborator

Add edge-delivery-redirect-maps example — URL redirect maps at the edge for Edge Delivery

Description

Adds a new edge-delivery-redirect-maps example: an edge-native way to serve URL redirect maps for an AEM Edge Delivery site. On each request the function checks the path against one or more published redirect sheets and answers a matched redirect (301/302) straight from the CDN POP; anything without a match passes through to the Edge Delivery origin. Edge Delivery uses a constrained, canonical URL space, so redirecting legacy/alternate URLs to canonical ones is a common need — and redirect sets get large (migrations, multiple brands/campaigns). Edge Delivery already authors redirects as a spreadsheet published as JSON, and this example consumes that same JSON directly at the edge.

It is the Edge Delivery counterpart to publish-delivery-redirect-maps, and builds directly on the existing edge-delivery-transformer example to keep the examples consistent and reduce variance — reusing its file layout, its shared src/lib helpers, and the hardcoded origin pattern.

It is deliberately much simpler than the AEMaaCS publish version, because Edge Delivery lets us drop three pieces:

  • No KV store and no maintenance endpoint — maps are loaded directly from JSON on the origin and cached at the edge, rather than swept into sharded KV by a scheduler.
  • No loopback — on a redirect miss the function fetches the page directly from the Edge Delivery origin (a different host from the customer domain), so there is no risk of routing back into the function and no need for the x-edgefunction-request sentinel.

The example focuses on the aspects specific to running redirect maps on Edge Functions:

  • Published-sheet input — each source is an Edge Delivery / Helix published sheet ({ "data": [ { "Source", "Destination" }, … ] }, or a bare array), so a real project can point it straight at an existing published redirect sheet.
  • Ordered, composable mapsREDIRECT_MAPS is a list of { sourcePath, redirectCode? } checked in order (first match wins), so independently-authored maps (e.g. a permanent migration map and a temporary campaigns map) compose with explicit precedence and can each use their own 301/302.
  • Two-layer caching — a per-POP readthrough cache of the fetched JSON (shared across instances) plus a per-instance in-memory memo of the parsed map, so a warm lookup is just a Map read, a cold instance is a cheap POP-cached refill + parse, and only a fully cold path reaches origin.
  • The sizing envelope — the README's Sizing and limits section explains how, without KV, map size is bounded by the sandbox's per-execution resource limits (heap for resident maps, the per-request computation budget for the on-request parse), and points to publish-delivery-redirect-maps as the heavier-duty alternative for very large sets.

To stay small and aligned with the other examples, it hardcodes the origin and the map definitions. Relative Destinations are emitted as relative Locations (resolved by the browser against the requested host), so — unlike the AEMaaCS version — no customer domain is hardcoded; absolute Destinations pass through for cross-host redirects. This is a reference example, not a turnkey production project.

Changes

  • examples/edge-delivery-redirect-maps/ — new example:
    • src/index.js — entry point; calls the redirect handler and logs the request
    • src/redirect.js — checks each map in order → 301/302 on a hit; transparent pass-through to the Edge Delivery origin on a miss (no loopback)
    • src/lib/redirects.js — two-layer cache: readthrough edge cache of the JSON + per-instance parsed-map memo, with a shared TTL
    • src/lib/parse.js — parses an Edge Delivery / Helix published sheet into a lookup Map
    • src/lib/location.js — resolves a Destination to a Location (relative stays relative; absolute passes through)
    • src/config.js — the origin, the ordered REDIRECT_MAPS ({ sourcePath, redirectCode? }), the default status, and the cache TTL (the single edit point)
    • src/lib/log.js, src/lib/response.js — shared helpers (from edge-delivery-transformer)
    • config/edgeFunctions.yaml — declares the service
    • config/cdn.yaml — origin-selector rule routing page-level GET/HEAD traffic to the function (no loopback condition)
    • test/ — unit tests (parse, location, response) and a sample published sheet
    • README.md, fastly.toml, package.json, package-lock.json, Makefile, renovate.json, LICENSE, CODE_OF_CONDUCT.md, .github/CONTRIBUTING.md, .gitignore, .npmrc
  • README.md (repository root) — added the example to the Examples list

Notes

  • Builds on edge-delivery-transformer (layout + shared helpers + hardcoded origin) so the two Edge Delivery examples read consistently.
  • No loopback and no maintenance endpoint: redirect maps are fetched from the origin on demand and cached (readthrough + parsed memo), not populated at deploy time or by a scheduler.
  • Relative Destinations produce relative Locations, so no customer domain is hardcoded; absolute Destinations cover cross-host redirects.
  • No third-party dependencies — only @fastly/js-compute (the AEMaaCS version's @noble/hashes is not needed here, as there is no KV change-detection).
  • npm test covers the pure-logic units (sheet parsing, Location resolution, responses); the cache/fetch and handler modules load only at build/runtime.
  • Without KV, map size is bounded by the Edge Function sandbox limits — see the README Sizing and limits section; for very large redirect sets, publish-delivery-redirect-maps (KV-sharded, off-path maintenance) is the heavier-duty option.

@krystiannowak
krystiannowak requested review from mpetria and phornig July 10, 2026 11: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.

1 participant