Serve multiple endpoints with Edge Functions
One AEM Edge Function can expose many HTTP endpoints. The examples in Build an API endpoint already show two endpoints (/status and /my-api) on a single JavaScript function. You do not deploy a separate function for each endpoint but just add endpoint matching logic to the same function.
Key point
edgeFunctions.yamlmy-edge-functioncdn.yamledgefunction-my-edge-function) origin, but each rule has its own path matching ruleindex.jsif statement per endpoint, and statement body has its own handler logicHow to add another endpoint
To expose a new endpoint such as /api/items:
- Add endpoint matching logic in
src/index.js. - Build and deploy the AEM Edge Function.
- Add an origin selector rule in
config/cdn.yamlfor the endpoint. - Deploy the CDN configuration
How to organize handler logic
Keep index.js focused on endpoint matching. Move handler logic into separate files as the API grows.
src/
├── index.js # fetch event handler and endpoint matching
├── my-api.js # handler for /my-api
├── items.js # handler for /api/items
└── lib/
└── response.js # shared 404 and 500 helpers
Match on method or path prefix
Endpoint matching is plain JavaScript. You are not limited to exact path equality.
HTTP method: Handle GET and POST on the same path with separate if statements.
if (url.pathname === "/api/items" && req.method === "GET") {
return await listItems(req);
}
if (url.pathname === "/api/items" && req.method === "POST") {
return await createItem(req);
}
Path prefix: Group related endpoints under a shared prefix, then dispatch to a handler inside a router module.
// src/index.js
if (url.pathname.startsWith("/api/")) {
return await apiRouter(req, url);
}
// src/api-router.js
async function apiRouter(req, url) {
// match the segment after the shared /api/ prefix
switch (url.pathname) {
case "/api/items":
return await itemsHandler(req);
case "/api/orders":
return await ordersHandler(req);
default:
return new Response("Not found", { status: 404 });
}
}
export { apiRouter };
Keep prefix routers shallow, meaning one prefix level that dispatches straight to a handler. If a prefix grows large, split it into separate prefixes with their own origin selector rules (for example, /api/catalog/ and /api/checkout/) instead of nesting routers under one prefix.
More code examples
The AEM Edge Functions boilerplate ships multiple endpoints in one function: