You can use Node.js handlers to respond to received events and execute the corresponding business logic. This topic describes the concepts and structure of Node.js handlers and provides examples.
What is a handler?
A handler of a function in Function Compute is the method that is used to process requests in function code. When a function is invoked, Function Compute uses the handler that you configure to process requests. You can configure a handler for a function by specifying the Handler parameter in the Function Compute console.
Handlers of Node.js functions in Function Compute follow the File name.Method name
format. For example, if your file name is index.js
or index.mjs
and your method name is handler
, the handler is index.handler
.
For more information about Function Compute functions and related operations, see Create an event function.
Configurations of handlers must conform to the configuration specifications of Function Compute. The configuration specifications vary based on the handler type.
Handler signatures
ECMAScript modules are supported by Function Compute in Node.js 18 and later. For Node.js 16 and earlier versions, Function Compute supports only CommonJS modules. For more information, see Specify an ECMAScript module as the handler.
The following sample code shows a simple event handler signature:
Node.js 18 or Node.js 20
ECMAScript modules
The sample code supports one-click deployment. You can deploy the sample code in Function Compute with one click. start-fc3-nodejs-es
// index.mjs
export const handler = async (event, context) => {
console.log("receive event: \n" + event);
return "Hello World!";
};
CommonJS modules
// 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');
};
Parameter description:
handler
indicates the method name, which corresponds to the value of the Handler parameter configured in the Function Compute console. For example, if you set Handler to index.handler
when you create a function, Function Compute loads the handler
method defined in index.js
and starts to execute code from handler.
Function Compute runtimes pass request parameters to handlers. The first parameter is the event
object, which contains the request payload information. The event
object is of the Buffer data type. You can convert event to another object type based on your business requirements. The second parameter is the context
object that provides context information during invocations. For more information, see Context.
We recommend that you use Async/Await instead of
callback
in Node.js 18 or later runtimes.Function Compute converts the returned result based on the type of the returned value.
Buffer type: The result is directly returned without changes.
Object type: The result is returned in the JSON format.
Other types: The results are returned as strings.
Async/Await
We recommend that you use Async/Await in Node.js 18 or later runtimes. Async/Await is a simple and easy-to-read way to write asynchronous code in Node.js without nested callbacks or method chaining.
If you use Node.js 16 or earlier, you must explicitly use callback
to send responses. Otherwise, a request timeout error occurs.
Compared with callback
, Async/Await provides the following benefits:
Better readability: The code in Async/Await mode is more linear and synchronous, and easier to understand and maintain. Async/Await prevents high-level nests and makes the code structure clearer.
Easy to debug and handle errors: You can use try-catch blocks to catch and handle errors in asynchronous operations more easily. Error stacks can be easily located and traced.
Higher efficiency: In most cases, callback functions must switch between different parts of code. Async/Await can reduce the number of context switches, thereby improving code efficiency.
Example 1: Parse JSON-formatted parameters
Sample code
When you pass JSON-formatted parameters into functions of Function Compute, Function Compute passes through the parameters, and you need to parse the parameters in the code. The following sample code provides an example on how to parse an event that is in the JSON format.
ECMAScript modules
This example supports only Node.js 18 and later.
export const handler = async (event, context) => {
var eventObj = JSON.parse(event.toString());
return eventObj['key'];
};
CommonJS modules
The sample code supports one-click deployment. You can deploy the sample code in Function Compute with one click. start-fc3-nodejs-json
exports.handler = function(event, context, callback) {
var eventObj = JSON.parse(event.toString());
callback(null, eventObj['key']);
};
Prerequisites
A Node.js function is created. For more information, see Create an event function. If you want to specify the code as an ECMAScript module, you must 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 details page, click the Code tab. In the code editor, enter the preceding sample code and click Deploy.
NoteIn the preceding sample code, the handler of the function is the
handler
method inindex.js
. If the handler of your function is different, use the actual handler configurations.On the Code tab, click the icon next to Test Function, select Configure Test Parameters from the drop-down list, enter the following sample test parameters, and then click OK.
{ "key": "value" }
Click Test Function on the Code tab.
After the function is executed, the execution result is returned. In this example,
value
is returned.
Example 2: Read and write OSS resources by using a temporary AccessKey pair
Sample code
You can use a temporary AccessKey pair that is provided by Function Compute to access Object Storage Service (OSS). The following code is used as an example:
ECMAScript modules
This example supports only Node.js 18 or later.
// 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
}
};
Parameter description:
context.credentials
: obtains the temporary AccessKey pair from the context parameter. This helps prevent hard-coding of sensitive information such as passwords in the code.myObj
: the name of the OSS object.Buffer.from('hello, fc', "utf-8")
: the object content to upload.return "put object"
: returns "put object" if the upload succeeds.throw err
: throws an exception if the upload fails.
CommonJS modules
The sample code supports one-click deployment. You can deploy the sample code in Function Compute with one 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);
});
};
Parameters description:
context.credentials
: obtains the temporary AccessKey pair from thecontext
parameter. This helps prevent hard-coding of sensitive information such as passwords in the code.myObj
: the name of the OSS object.Buffer.from('hello, fc', "utf-8")
: the object content to upload.callback(null, 'put object')
: returnsput object
if the upload succeeds.callback(err)
: returnserr
if the upload fails.
Before you start
Configure a role that has permissions to access OSS. For more information, see Grant Function Compute permissions to access other Alibaba Cloud services.
Create a function in a Node.js runtime. For more information, see Create an event function. If you want to specify the code as an ECMAScript module, you must 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.
(Optional) On the Function Details page, click the Code tab. In the lower part of the WebIDE page, choose
. Then, run the following command to install ali-oss dependencies:npm install ali-oss --save
After the installation is complete, you can see that the
node_modules
folder is generated in the code directory on the left side of WebIDE. The folder contains theali-oss
directory and other dependent libraries.On the Function Details page, click the Code tab. In the code editor, enter the preceding sample code, save the code, and then click Deploy.
NoteIn the preceding sample code, the handler for the function is the
handler
method inindex.js
orindex.mjs
. If the handler of your function is different, use the actual handler configurations.Replace
region
andbucket
in the preceding sample code with the actual values.
Click Test Function.
After the function is executed, the execution result is returned. In this example,
put object
is returned.
Example 3: Call external commands
You can use a Node.js program to create a fork
process to call external commands. For example, you can use the child_process
module to call the ls -l
command of Linux and output the list of files in the current directory. Sample code:
ECMAScript modules
This example supports only Node.js 18 or later.
'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 modules
The sample code supports one-click deployment. You can deploy the sample code in Function Compute with one 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: Use an HTTP trigger to invoke a function
Sample code
You can use a URL that is provided by an HTTP trigger to invoke a function in Function Compute. The following sample code shows an example:
If the Authentication Method parameter of the HTTP trigger is set to No Authentication, you can use Postman or curl to invoke the function. For more information, see Procedure.
If the Authentication Method parameter of the HTTP trigger is set to Signature Authentication or JWT Authentication, you can use the signature method or JWT authentication method to invoke the function. For more information, see Authentication.
For more information about formats of request payloads and response payloads of HTTP triggers, see Use an HTTP trigger to invoke a function.
ECMAScript modules
This example supports only Node.js 18 or later.
'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 modules
The sample code supports one-click deployment. You can deploy the sample code in Function Compute with one 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
You have used the preceding sample code to create a function in a Node.js runtime and created an HTTP trigger for the function. For more information, see Create an event function and Configure an HTTP trigger that invokes a function with HTTP requests. If you want to specify the code as an ECMAScript module, you must 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 details page, click the Configuration tab. In the left-side navigation pane, click Trigger. On the Trigger page, obtain the public endpoint of the HTTP trigger.
Run the following command by using curl to invoke 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.run
is the obtained public endpoint of the HTTP trigger.The following result 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!curl: (3) URL using bad/illegal format or missing URL
Example 5: Use an HTTP trigger to download files
Sample code
If you want to return an image, compressed package, or binary file by using code, you can use an HTTP trigger. The following sample code provides an example:
ECMAScript modules
This example supports only 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 modules
// 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
You have used the preceding sample code to create a function in a Node.js runtime and created an HTTP trigger for the function. For more information, see Create an event function and Configure an HTTP trigger that invokes a function with HTTP requests. If you want to specify the code as an ECMAScript module, you must 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 details page, click the Code tab. In the page that appears, click
to open the terminal window. Run thenpm install mime@2
command to install the mime library. After the installation is complete, click Deploy.On the Triggers tab of the function configuration page, copy the value of Public Endpoint of the HTTP trigger, paste the public endpoint in a browser, and then press Enter.
After that, the function is executed and a file is downloaded to your on-premises machine.