Node.js v4 Programming Model¶
This deep dive explains the Node.js v4 code-first model for Azure Functions. It covers registration APIs, trigger patterns, request and response handling, and practical composition patterns for production-ready apps.
Main Content¶
The v4 model removes per-function function.json authoring for normal scenarios and registers triggers directly in code.
flowchart TD
A[Host starts] --> B["Load @azure/functions app object"]
B --> C[Register app.http app.timer app.storageQueue app.storageBlob]
C --> D[Index function metadata]
D --> E[Accept trigger events]
E --> F[Invoke handler with context] Project Layout¶
project-root/
├── src/
│ └── functions/
│ ├── httpTrigger.js
│ ├── timerTrigger.js
│ └── queueTrigger.js
├── host.json
├── local.settings.json
└── package.json
HTTP Trigger Pattern¶
const { app } = require('@azure/functions');
app.http('helloHttp', {
methods: ['GET'],
authLevel: 'function',
route: 'hello/{name?}',
handler: async (request, context) => {
const name = request.params.name || request.query.get('name') || 'world';
context.log(`Request received for ${name}`);
return {
status: 200,
jsonBody: {
message: `Hello, ${name}`,
model: 'nodejs-v4'
}
};
}
});
Timer Trigger Pattern¶
const { app } = require('@azure/functions');
app.timer('cleanupTimer', {
schedule: '0 */5 * * * *',
handler: async (timer, context) => {
context.log(`Timer fired at ${timer.scheduleStatus?.last || 'first-run'}`);
}
});
Queue Trigger Pattern¶
const { app } = require('@azure/functions');
app.storageQueue('processOrders', {
queueName: 'orders',
connection: 'AzureWebJobsStorage',
handler: async (queueItem, context) => {
context.log(`Processing order ${queueItem.orderId}`);
}
});
Blob Trigger Pattern¶
const { app } = require('@azure/functions');
app.storageBlob('ingestBlob', {
path: 'incoming/{name}',
connection: 'AzureWebJobsStorage',
handler: async (blob, context) => {
context.log(`Blob length: ${blob.length}`);
}
});
ESM Variant¶
import { app } from '@azure/functions';
app.http('ping', {
methods: ['GET'],
handler: async (_request, context) => {
context.log('Ping called');
return { body: 'pong' };
}
});
Request Data Access¶
- Query:
request.query.get('name') - Route params:
request.params.name - Body JSON:
await request.json() - Headers:
request.headers.get('x-correlation-id')
Response Construction¶
- JSON response:
{ status: 200, jsonBody: { ok: true } } - Text response:
{ status: 200, body: 'ok' } - Error response:
{ status: 400, jsonBody: { error: 'invalid-input' } }
Local Initialization¶
func init MyProject --worker-runtime node --language javascript --model v4
func new --template "HTTP trigger" --name httpTrigger
func start