Migrando padrões de handler em Functions
As Azion Functions suportam dois padrões de handler: ES Modules (recomendado) e Service Worker (legado). Este guia explica as diferenças entre eles e como migrar suas functions existentes para o padrão ES Modules.
Padrões suportados
ES Modules (recomendado)
O padrão ES Modules é a forma recomendada de estruturar suas functions na Azion. Ele oferece uma sintaxe moderna e limpa, com suporte nativo em produção e melhor desempenho.
export default { fetch: (request, env, ctx) => { return new Response('Hello World'); }, firewall: (request, env, ctx) => { // Lógica de firewall ctx.deny(); }};Service Worker (legado)
O padrão Service Worker é mantido para compatibilidade com código legado. Se você estiver usando esse padrão, a Azion recomenda migrar para ES Modules.
addEventListener('fetch', (event) => { event.respondWith(handleRequest(event.request));});
addEventListener('firewall', (event) => { // Lógica de firewall event.deny();});
async function handleRequest(request) { return new Response('Hello World');}Parâmetros dos handlers
fetch(request, env, ctx)
| Parâmetro | Tipo | Descrição |
|---|---|---|
request | Request | O objeto da requisição HTTP recebida |
env | Object | Variáveis de ambiente e bindings |
ctx | Object | Contexto de execução. Use ctx.waitUntil(promise) para estender o tempo de vida da function para tarefas assíncronas |
firewall(request, env, ctx) — ES Modules
| Parâmetro | Tipo | Descrição |
|---|---|---|
request | Request | O objeto da requisição HTTP recebida |
env | Object | Variáveis de ambiente e bindings |
ctx | Object | Contexto de execução. Chame ctx.deny() para bloquear a requisição imediatamente. Se ctx.deny() não for chamado, a requisição continua para o handler fetch |
Evento de firewall — Service Worker
| Propriedade | Descrição |
|---|---|
event.request | Acesso ao objeto Request |
event.deny() | Bloqueia a requisição imediatamente. Se não for chamado, a requisição continua para o handler fetch |
Migrando de Service Worker para ES Modules
Handler fetch básico
Antes (Service Worker):
addEventListener('fetch', (event) => { event.respondWith(handleRequest(event.request));});
async function handleRequest(request) { const url = new URL(request.url);
if (url.pathname === '/api/hello') { return new Response(JSON.stringify({ message: 'Hello World' }), { headers: { 'Content-Type': 'application/json' } }); }
return new Response('Not Found', { status: 404 });}Depois (ES Modules):
export default { fetch: async (request, env, ctx) => { const url = new URL(request.url);
if (url.pathname === '/api/hello') { return new Response(JSON.stringify({ message: 'Hello World' }), { headers: { 'Content-Type': 'application/json' } }); }
return new Response('Not Found', { status: 404 }); }};Handler firewall
Antes (Service Worker):
addEventListener('fetch', (event) => { event.respondWith(handleRequest(event.request));});
addEventListener('firewall', (event) => { const clientIP = event.request.headers.get('X-Forwarded-For'); const userAgent = event.request.headers.get('User-Agent');
// Bloquear requisições de bots if (userAgent && userAgent.includes('bot')) { event.deny(); return; }
// Bloquear IPs específicos if (clientIP === '192.168.1.100') { event.deny(); return; }
// Permitir que a requisição continue para o handler fetch});
async function handleRequest(request) { return new Response('Hello World');}Depois (ES Modules):
export default { fetch: async (request, env, ctx) => { return new Response('Acesso concedido'); },
firewall: async (request, env, ctx) => { const clientIP = request.headers.get('X-Forwarded-For'); const userAgent = request.headers.get('User-Agent');
// Bloquear requisições de bots if (userAgent && userAgent.includes('bot')) { ctx.deny(); return; }
// Bloquear IPs específicos if (clientIP === '192.168.1.100') { ctx.deny(); return; }
// Permitir que a requisição continue para o handler fetch return; }};Usando waitUntil para tarefas assíncronas
export default { fetch: async (request, env, ctx) => { // Use waitUntil para tarefas assíncronas que não devem bloquear a resposta ctx.waitUntil(logRequest(request));
return new Response('Hello World'); }};
async function logRequest(request) { console.log(`Requisição para: ${request.url}`);}Firewall avançado com regras baseadas em path
export default { fetch: async (request, env, ctx) => { return new Response('Acesso concedido'); },
firewall: async (request, env, ctx) => { const url = new URL(request.url); const userAgent = request.headers.get('User-Agent'); const clientIP = request.headers.get('X-Forwarded-For');
// Bloquear requisições de bots if (userAgent && userAgent.includes('bot')) { ctx.deny(); return; }
// Restringir acesso a paths de admin por faixa de IP if (url.pathname.startsWith('/admin')) { if (!clientIP || !clientIP.startsWith('192.168.')) { ctx.deny(); return; } }
// Permitir que a requisição continue para o handler fetch return; }};Padrões não suportados
Os seguintes padrões não são suportados pelas Azion Functions. Se o seu código utilizar algum deles, migre para o padrão ES Modules.
// ❌ Export direto de funçãoexport default function(request) { return new Response('Hello');}
// ❌ Named exportsexport function fetch(request) { return new Response('Hello');}
// ❌ Sem exportfunction handleRequest(request) { return new Response('Hello');}Solução de problemas
”Unsupported handler pattern detected”
Esse erro aparece quando o código não segue nenhum dos padrões suportados. Para resolver, migre para o padrão ES Modules:
export default { fetch: async (request, env, ctx) => { return new Response('Hello World'); }};Como alternativa temporária, use o padrão Service Worker:
addEventListener('fetch', (event) => { event.respondWith(handleRequest(event.request));});
async function handleRequest(request) { return new Response('Hello World');}Recursos relacionados
- Primeiros passos com Functions
- Visão geral de Functions
- Referência da API do Azion Runtime
- Functions com Firewall