Middleware
Directory-level middleware for App Functions.
Advanced Feature
For most authentication and authorization needs, use Access Rules instead. Middleware is useful for HTTP-level concerns like webhook verification or request logging.
Overview
Place a _middleware.ts file in any directory under functions/ to run code before all functions in that directory and its subdirectories.
Creating Middleware
// functions/_middleware.ts (applies to ALL functions)
import { defineFunction, FunctionError } from '@edgebase/shared';
export default defineFunction(async ({ auth }) => {
if (!auth) {
throw new FunctionError('unauthenticated', 'Login required');
}
// Return nothing to continue to the next middleware / handler
});
Directory Scoping
Middleware only applies to functions in its directory and subdirectories:
functions/
_middleware.ts <- applies to everything
public/
health.ts <- only root middleware
admin/
_middleware.ts <- applies to admin/* functions
dashboard.ts <- root + admin middleware
users/
[userId].ts <- root + admin middleware
Execution Order
Middlewares execute from root to most specific directory:
Request to /api/functions/admin/users/abc123
1. functions/_middleware.ts (root)
2. functions/admin/_middleware.ts (admin/)
3. functions/admin/users/[userId].ts (handler)
Use Cases
Webhook Secret Verification
// functions/(webhooks)/_middleware.ts
export default defineFunction(async ({ request }) => {
const secret = request.headers.get('x-webhook-secret');
if (secret !== process.env.WEBHOOK_SECRET) {
throw new FunctionError('unauthenticated', 'Invalid webhook secret');
}
});
Request Logging
// functions/_middleware.ts
export default defineFunction(async ({ request, auth }) => {
console.log(`[${new Date().toISOString()}] ${request.method} ${request.url} user=${auth?.id ?? 'anonymous'}`);
});