You can use a Node.js handler to respond to events and execute your business logic. This topic describes the concept and structure of Node.js handlers and provides examples.
What is a handler?
The handler for an FC function is the method in your function code that processes requests. When your FC function is invoked, Function Compute runs the configured handler to process the request. You can configure the handler in the Function Compute console by using the Handler parameter.
For a Node.js FC function, the handler format is filename.methodName. For example, if your file is named index.js or index.mjs and the method is named handler, the handler is index.handler.
For more information about FC functions and related operations, see Create an event-triggered function.
Configurations of handlers must conform to the configuration specifications of Function Compute. The configuration specifications vary based on the handler type.
Handler signature
Function Compute supports ECMAScript (ES) modules starting from the Node.js 18 runtime. Before that (in Node.js 16 and earlier versions), Function Compute only supported CommonJS modules. For more information, see Specify a handler as an ES module.
A simple event handler has the following signature:
Node.js 18 or Node.js 20
ES module
This sample code supports one-click deployment. You can deploy the code directly in Function Compute (FC).start-fc3-nodejs-es
// index.mjs
export const handler = async (event, context) => {
console.log("receive event: \n" + event);
return "Hello World!";
};
CommonJS module
// index.js
exports.handler = async function(event, context) {
console.log("receive event: \n" + event);
return "Hello World!";
};
Node.js 16 and earlier
// index.js
exports.handler = async function(event, context, callback) {
console.log("event: \n" + event);
callback(null, 'hello world');
};
The sample code above is described as follows:
handler is the method name, which corresponds to the Handler configured in the Function Compute console. For example, if you specify index.handler as the Handler when you create a function, Function Compute loads the handler function defined in index.js and starts execution.
The Function Compute runtime passes request parameters to the request handler. The first parameter is the event object, which contains the request payload. The event object is of the Buffer type, and you can convert it to the object type that you need. The second parameter is the context object, which provides runtime context information for the invocation. For more information, see Context.
When using the Node.js 18 or later runtime, use the Async/Await feature instead of the
callback.Function Compute converts the returned result based on its type.
Buffer type: Returned as is.
Object type: Converted to the JSON format and returned.
Other types: Converted to a string and returned.
Async/Await
When you use the Node.js 18 or later runtime environment, we recommend that you use the Async/Await approach. Async/Await is a concise and readable way to write asynchronous code in Node.js that avoids nested callbacks or chained calls.
If you use the Node.js 16 runtime or earlier, you must explicitly use the callback method to send a response. Otherwise, the request times out.
The Async/Await approach has the following advantages compared to callback functions callback:
Improved readability: Code that uses
async/awaitis more linear and synchronous. This makes the code easier to understand and maintain. It avoids deeply nested callbacks, which results in a clearer code structure.Simpler debugging and error handling: You can use
try-catchblocks to more easily capture and handle errors in asynchronous operations. The error stack is clearer, which lets you trace the source of an error more accurately.Higher efficiency: Callbacks often require switching between different parts of the code. The
async/awaitapproach reduces the number of context switches, which improves code efficiency.
Example 1: Parse JSON-formatted parameters
Sample code
Function Compute passes JSON-formatted parameters directly to your function. You must parse these parameters in your code. The following code shows how to parse a JSON-formatted event.
ES module
This example is supported only in runtimes of Node.js 18 and later.
export const handler = async (event, context) => {
var eventObj = JSON.parse(event.toString());
return eventObj['key'];
};
CommonJS module
This sample code supports one-click deployment. You can deploy this code to Function Compute (FC) with a single click.start-fc3-nodejs-json
exports.handler = function(event, context, callback) {
var eventObj = JSON.parse(event.toString());
callback(null, eventObj['key']);
};
Prerequisites
Create a Node.js function. For more information, see Create an event-triggered function. If you want to specify your code as an ES module, select Node.js 18 or Node.js 20 as the runtime when you create the function.
Procedure
Log on to the Function Compute console. In the left-side navigation pane, click Functions.
In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.
On the function configuration page, select the Code tab. In the code editor, enter the preceding sample code and then click Deploy.
NoteThe handler for the function in the preceding sample code is the
handlermethod inindex.js. If your function's handler is configured differently, update the corresponding file and method.On the Code tab, click the
icon to the right of Test Function. From the drop-down list, select Configure Test Parameters. Enter the following sample test parameters and then click OK.{ "key": "value" }Click Test Function.
After the function runs successfully, check the response. The response is
value.
Example 2: Securely read and write OSS resources using a temporary AccessKey pair
Sample code
Use the temporary AccessKey pair that Function Compute provides to access Object Storage Service (OSS). The following code is an example.
ES module
This example runs only in Node.js 18 or later runtimes.
// index.mjs
import OSSClient from 'ali-oss';
export const handler = async (event, context) => {
console.log(event.toString());
var ossClient = new OSSClient({
accessKeyId: context.credentials.accessKeyId,
accessKeySecret: context.credentials.accessKeySecret,
stsToken: context.credentials.securityToken,
region: 'oss-cn-shenzhen',
bucket: 'my-bucket',
});
try {
const uploadResult = await ossClient.put('myObj', Buffer.from('hello, fc', "utf-8"));
console.log('upload success, ', uploadResult);
return "put object"
} catch (error) {
throw error
}
};
Code description:
context.credentials: Obtains the temporary AccessKey pair from the context parameter. This avoids hardcoding sensitive information such as passwords in the code.myObj: The name of the OSS object.Buffer.from('hello, fc', "utf-8"): The content of the object to upload.return "put object": If the upload is successful,put objectis returned.throw err: If the upload fails, an exception is thrown.
CommonJS module
This sample code supports one-click deployment. Deploy this code to Function Compute (FC) with a single click.start-fc3-nodejs-oss
var OSSClient = require('ali-oss');
exports.handler = function (event, context, callback) {
console.log(event.toString());
var ossClient = new OSSClient({
accessKeyId: context.credentials.accessKeyId,
accessKeySecret: context.credentials.accessKeySecret,
stsToken: context.credentials.securityToken,
region: `oss-${context.region}`,
bucket: process.env.BUCKET_NAME,
});
ossClient.put('myObj', Buffer.from('hello, fc', "utf-8")).then(function (res) {
callback(null, 'put object');
}).catch(function (err) {
callback(err);
});
};
Code description:
context.credentials: Obtains the temporary AccessKey pair from thecontextparameter. This avoids hardcoding sensitive information such as passwords in the code.myObj: The name of the OSS object.Buffer.from('hello, fc', "utf-8"): The content of the object to upload.callback(null, 'put object'): If the upload is successful,put objectis returned.callback(err): If the upload fails,erris returned.
Prerequisites
Configure a role for the service that has permissions to access OSS. For more information, see Grant Function Compute permissions to access other cloud services by using function roles.
Create a function that uses the Node.js runtime. For more information, see Create an event-triggered function. If you want to specify the code as an ES module, set the runtime to Node.js 18 or Node.js 20 when you create the function.
Procedure
Log on to the Function Compute console. In the left-side navigation pane, click Functions.
In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.
(Optional) On the Function Details tab of the function, click the Code tab. In the WebIDE section, choose to open a terminal. Then, run the following command to install the ali-oss dependency.
npm install ali-oss --saveAfter the installation is complete, the
node_modulesfolder is generated in the code directory on the left side of the WebIDE. The folder contains theali-ossdirectory and other dependency libraries.On the Function Details tab of the function, click the Code tab. In the code editor, enter the sample code provided above. Then, save the code and click Deploy.
NoteIn the sample code, the handler of the function is the
handlermethod in theindex.jsorindex.mjsfile. If your function uses a different handler, update the file and method accordingly.In the sample code, you must set
regionandbucketbased on your requirements.
Click Test Function.
After the function is executed, view the returned result. The result is
put object.
Example 3: Call an external command
A Node.js program can also create a fork process to call external commands. For example, you can use the child_process module to call the Linux ls -l command and list the files in the current directory. The following code provides an example.
ES module
This example runs only in Node.js 18 and later runtimes.
'use strict';
import { exec } from 'child_process';
import { promisify } from 'util';
const execPromisify = promisify(exec);
export const handler = async (event, context) => {
try {
const { stdout, stderr } = await execPromisify("ls -l");
console.log(`stdout: ${stdout}`);
if (stderr !== "") {
console.error(`stderr: ${stderr}`);
}
return stdout;
} catch (error) {
console.error(`exec error: ${error}`);
return error;
}
}
CommonJS module
This code supports one-click deployment. You can deploy this code to Function Compute (FC) with a single click.start-fc3-nodejs-exec
'use strict';
var exec = require('child_process').exec;
exports.handler = (event, context, callback) => {
console.log('start to execute a command');
exec("ls -l", function(error, stdout, stderr){
callback(null, stdout);
});
}Example 4: Call a function using an HTTP trigger
Sample code
Use the URL provided by the HTTP trigger to call the function. The following code is an example.
If the Authentication Method for the HTTP trigger is set to No Authentication, use Postman or a curl command to call the function. For more information, see Procedure.
If the Authentication Method for the HTTP trigger is set to Signature Authentication, JWT authentication or Bearer authentication, use the corresponding authentication method to call the function. For more information, see Authentication.
For information about the request and response payload formats for calls made by HTTP triggers, see Call a function using an HTTP trigger.
ES module
This example is supported only in Node.js 18 or later runtimes.
'use strict';
export const handler = async (event, context) => {
const eventObj = JSON.parse(event);
console.log(`receive event: ${JSON.stringify(eventObj)}`);
let body = 'Hello World!';
// get http request body
if ("body" in eventObj) {
body = eventObj.body;
if (eventObj.isBase64Encoded) {
body = Buffer.from(body, 'base64').toString('utf-8');
}
}
console.log(`receive http body: ${body}`);
return {
'statusCode': 200,
'body': body
};
}
CommonJS module
This sample code supports one-click deployment. You can deploy this code to Function Compute (FC) with a single click.start-fc3-nodejs-http
'use strict';
exports.handler = (event, context, callback) => {
const eventObj = JSON.parse(event);
console.log(`receive event: ${JSON.stringify(eventObj)}`);
let body = 'Hello World!';
// get http request body
if ("body" in eventObj) {
body = eventObj.body;
if (eventObj.isBase64Encoded) {
body = Buffer.from(body, 'base64').toString('utf-8');
}
}
console.log(`receive http body: ${body}`);
callback(null, {
'statusCode': 200,
'body': body
});
}
Prerequisites
A function that uses the Node.js runtime and an HTTP trigger are created based on the preceding examples. For more information, see Create an event-triggered function and Configure an HTTP trigger. If you want to specify the code as an ES module, select Node.js 18 or Node.js 20 for the runtime when you create the function.
Procedure
Log on to the Function Compute console. In the left-side navigation pane, click Functions.
In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.
On the function details page, click the Triggers tab. On the Triggers page, obtain the public endpoint of the HTTP trigger.
Run the following command in a curl tool to call the function.
curl -i "https://test-nodejs-dlgxxr****.cn-shanghai.fcapp.run" -d 'Hello World!'In the preceding command,
https://test-nodejs-dlgxxr****.cn-shanghai.fcapp.runis the public endpoint of the HTTP trigger.The following response is returned.
HTTP/1.1 200 OK Access-Control-Expose-Headers: Date,x-fc-request-id Content-Disposition: attachment Content-Length: 12 Content-Type: text/html; charset=utf-8 Etag: W/"c-Lve95gjOVATpfV8EL5X4nxwjKHE" X-Fc-Request-Id: 1-65d866a8-15d8796a-cb9b4feb69ca X-Powered-By: Express Date: Fri, 23 Feb 2024 09:34:34 GMT Hello World!
Example 5: Use an HTTP trigger to download a file
Sample code
To return an image, a compressed package, or a binary file from your code, use an HTTP trigger. The following code provides an example.
ES module
This example is supported only in runtimes of Node.js 18 or later.
// index.mjs
'use strict';
import mime from 'mime';
import fs from 'fs/promises';
import path from 'path';
export const handler = async (event, context) => {
const fileContent = 'This is a sample text file created in the code.';
const fileName = 'sample.txt';
const filePath = path.join('/tmp', fileName);
try {
await fs.writeFile(filePath, fileContent);
const mimeType = mime.getType(filePath);
if (!mimeType) {
throw new Error('Unable to determine MIME type');
}
const fileData = await fs.readFile(filePath);
const fileBase64 = Buffer.from(fileData).toString('base64');
const fcResponse = {
'statusCode': 200,
'headers': {
'Content-Type': mimeType,
'Content-Disposition': `attachment; filename="${fileName}"`,
},
'body': fileBase64,
'isBase64Encoded': true
};
console.log('File generated and fetched successfully.');
return fcResponse;
} catch (err) {
console.error(err);
return {
'statusCode': 500,
'body': err.message
};
}
};CommonJS module
// index.js
'use strict';
const mime = require('mime');
const fs = require('fs');
const path = require('path');
exports.handler = async (event, context, callback) => {
const fileContent = 'This is a sample text file created in the code.';
const fileName = 'sample.txt';
const filePath = path.join('/tmp', fileName);
try {
fs.writeFileSync(filePath, fileContent);
const mimeType = mime.getType(filePath);
if (!mimeType) {
throw new Error('Unable to determine MIME type');
}
const fileData = fs.readFileSync(filePath);
const fileBase64 = Buffer.from(fileData).toString('base64');
const fcResponse = {
'statusCode': 200,
'headers': {
'Content-Type': mimeType,
'Content-Disposition': `attachment; filename="${fileName}"`,
},
'body': fileBase64,
'isBase64Encoded': true
};
console.log('File generated and fetched successfully.');
callback(null, fcResponse);
} catch (err) {
console.error(err);
callback(null, {
'statusCode': 500,
'body': err.message
});
}
};
Prerequisites
Create a function that uses the Node.js runtime and an HTTP trigger based on the preceding examples. For more information, see Create an event-triggered function and Configure an HTTP trigger. If you want to specify the code as an ES module, set the runtime to Node.js 18 or Node.js 20 when you create the function.
Procedure
Log on to the Function Compute console. In the left-side navigation pane, click Functions.
In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.
On the function details page, click the Code tab, and then choose to open a terminal window. Run the
npm install mime@2command to install the mime library. After the installation is complete, click Deploy.On the Trigger tab of the function, obtain the Internet Endpoint of the HTTP trigger. Copy the URL to your browser and press Enter.
After you press Enter, the function is triggered. If the function runs successfully, the file is downloaded to your local machine.