Azure Functions provide a serverless compute experience that enables you to build and run event-driven applications and services without managing infrastructure. This document outlines the programming model for developing Azure Functions using JavaScript.
Core Concepts
Triggers and Bindings
Azure Functions operate on a trigger-and-binding model. A trigger defines how a function is invoked (e.g., an HTTP request, a timer, a message arriving in a queue). Bindings connect your function to other services, allowing you to easily read input data and write output data without writing boilerplate code for service integration.
Function Runtime
The Azure Functions runtime manages the execution of your functions, including scaling, lifecycle management, and handling incoming events. You write your function code, and the runtime takes care of the rest.
Developing JavaScript Functions
Project Structure
A typical Azure Functions project using JavaScript has the following structure:
my-function-app/
├── MyHttpTrigger/
│ ├── index.js
│ └── function.json
├── MyTimerTrigger/
│ ├── index.js
│ └── function.json
├── host.json
└── local.settings.json
MyHttpTrigger/,MyTimerTrigger/: These are your function folders. Each function has its own folder.index.js: Contains your function's JavaScript code.function.json: Defines the function's triggers and bindings.host.json: Contains global configuration options that affect all functions in the function app.local.settings.json: Stores app settings, connection strings, and settings for local development.
function.json
This JSON file is crucial for defining how your function is triggered and how it interacts with other services. Here's an example for an HTTP trigger:
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
Key properties:
type: The type of trigger or binding (e.g.,httpTrigger,blob,queue).direction: Can beinfor input oroutfor output.name: The name used to access the trigger or binding data within your function code.methods(forhttpTrigger): An array of HTTP methods the trigger should respond to.
index.js (Function Code)
Your JavaScript function is typically exported as an asynchronous function that accepts the trigger input as its first argument and returns the output binding results.
HTTP Trigger Example
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
const name = (req.query.name || (req.body && req.body.name));
const responseMessage = name
? "Hello, " + name + ". This HTTP triggered function executed successfully."
: "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.";
context.res = {
status: 200,
body: responseMessage
};
};
In this example:
context: An object providing access to runtime information, logging, and output bindings.req: The input object representing the HTTP request (defined by thehttpTriggerbinding withname: "req").context.log(): Used for logging messages that appear in the Functions logs.context.res: The output object used to send the HTTP response (defined by thehttpbinding withname: "res").
Timer Trigger Example
For a timer trigger, the function.json would look like:
{
"scriptFile": "index.js",
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */5 * * * *"
}
]
}
And the index.js:
module.exports = async function (context, myTimer) {
const timeStamp = new Date().toISOString();
if (myTimer.isPastDue) {
context.log('JavaScript is running late!');
}
context.log('JavaScript timer trigger function executed at', timeStamp);
};
The timer trigger passes an object (myTimer in this case) that contains information about the timer event, such as whether it's past due.
Common Bindings
HTTP Trigger
Invoked by an HTTP request.
type: "httpTrigger"
direction: "in"
name: "req"
Common properties: methods, authLevel.
HTTP Output Binding
Used to return an HTTP response.
type: "http"
direction: "out"
name: "res"
Timer Trigger
Invoked on a schedule.
type: "timerTrigger"
direction: "in"
name: "myTimer"
Common properties: schedule (using CRON expressions).
Blob Input Binding
Reads data from a blob storage container.
type: "blob"
direction: "in"
name: "myBlob"
Common properties: path (e.g., samples-workitems/{name}), connection.
Blob Output Binding
Writes data to a blob storage container.
type: "blob"
direction: "out"
name: "outputBlob"
Common properties: path (e.g., samples-workitems/output/{name}), connection.
Queue Trigger
Invoked when a message is added to a queue.
type: "queueTrigger"
direction: "in"
name: "myQueueItem"
Common properties: queueName, connection.
Queue Output Binding
Writes a message to a queue.
type: "queue"
direction: "out"
name: "outputQueue"
Common properties: queueName, connection.
Context Object
The context object provides several useful properties and methods:
context.log(message, ...args): Logs messages to the Azure Functions logs.context.bindingData: Contains metadata about the trigger and bindings.context.done([err], [result]): (Deprecated but still functional) Signals completion of the function execution. Modern functions use async/await and return promises.context.res: Used to set the output for output bindings, particularly for HTTP responses.context.df: For orchestrations within Durable Functions.
Environment Variables and Settings
You can access application settings and connection strings defined in local.settings.json (for local development) or in the Azure portal (for deployed functions) via environment variables. The Functions runtime automatically makes these available.
// Accessing a setting named 'MyCustomSetting'
const customSetting = process.env.MyCustomSetting;
local.settings.json is not committed to source control. It contains sensitive information. Use Azure Key Vault or Application Settings in Azure for secure storage of secrets in production.
Error Handling
Use standard JavaScript error handling mechanisms like try...catch blocks and Promises to manage errors effectively. Unhandled exceptions will cause the function execution to fail.
Next Steps
Explore specific triggers and bindings for the services you want to integrate with. Learn about advanced topics like Durable Functions for stateful orchestrations and managing dependencies with npm.