Migrate handler patterns in Functions
Move a function from the legacy Service Worker handler to the ES Modules handler, with the before and after for fetch and firewall.
Functions supports two handler patterns: ES Modules, which Azion recommends, and Service Worker, which Azion maintains for backward compatibility. Existing Service Worker code keeps running, so the migration is work to schedule rather than a break to repair. Code that follows neither pattern is not supported.
Supported handler patterns
Both patterns give the handler the same request and the same execution context. They differ in how the code receives them.
ES Modules
An ES Modules function exports a default object. Its fetch method receives the request, the environment variables and bindings, and the execution context. A firewall method receives the same three arguments:
A default export whose fetch method takes request, env, and ctx follows this pattern, whether it is an object literal or the application instance a framework returns. An application instance built with a framework qualifies, so a Hono app exported with export default app is an ES Modules handler. For a function written that way, refer to Build a RESTful tasks API with Functions and SQL Database.
Service Worker
A Service Worker function registers a listener with addEventListener. The listener reads the request from an event object, and it answers with event.respondWith:
Handler parameters
An ES Modules handler receives three arguments. A Service Worker listener receives one event object that carries the same values. For the signature as the runtime reference states it, refer to Handlers.
fetch(request, env, ctx) in ES Modules
| Parameter | Type | Description |
|---|---|---|
request | Request | The incoming HTTP request object |
env | Object | Environment variables and bindings |
ctx | Object | Execution context. Use ctx.waitUntil(promise) to extend the lifetime of the function for async tasks |
firewall(request, env, ctx) in ES Modules
| Parameter | Type | Description |
|---|---|---|
request | Request | The incoming HTTP request object |
env | Object | Environment variables and bindings |
ctx | Object | Execution context. Call ctx.deny() to block the request immediately. If ctx.deny() is not called, the request continues to the fetch handler |
The event object in Service Worker
| Property | Description |
|---|---|
event.request | Access to the Request object |
event.deny() | Blocks the request immediately. If not called, the request continues to the fetch handler |
Migrate the handler
The logic stays the same in both patterns. What changes is where the handler reads the request and where it returns the response.
Migrate the fetch handler
The listener becomes a fetch method. The request arrives as the first argument, not as a property of the event.
Service Worker code registers the listener and delegates to a named function:
The ES Modules replacement moves the same logic into the fetch method and returns the response directly:
Migrate the firewall handler
Three names change: the listener becomes a firewall method, event.request becomes request, and event.deny() becomes ctx.deny().
Service Worker code reads the headers from the event and blocks with event.deny():
The ES Modules replacement reads the headers from request and blocks with ctx.deny():
Use the execution context
The ctx argument carries the two calls an ES Modules handler makes on the invocation itself.
Move async work off the response path
ctx.waitUntil(promise) extends the lifetime of the function past the response. Pass it the work whose result the response does not need:
Block requests by path
The firewall method receives the whole request. The handler can read the URL and apply one rule per path. This handler blocks bots everywhere and restricts /admin to a single address range:
Unsupported patterns
Azion Runtime reports Unsupported handler pattern detected when the code matches neither supported pattern. Three shapes produce it:
All three fail the same requirement: the default export must be an object that carries a fetch method. Rewrite the code in the ES Modules pattern to clear the error. The Service Worker pattern also clears it, and Azion recommends ES Modules for new code.
For failures that the handler shape does not explain, refer to Troubleshoot function execution and logs.