您可以使用Node.js請求處理常式響應接收到的事件並執行相應的商務邏輯。本文介紹Node.js請求處理常式的相關概念、結構特點和樣本。
什麼是請求處理常式
FC函數的請求處理常式,是函數代碼中處理請求的方法。當您的FC函數被調用時,Function Compute會運行您提供的Handler方法處理請求。您可以通過Function Compute控制台的請求處理常式參數配置Handler。
對Node.js語言的FC函數而言,您的請求處理常式格式為檔案名稱.方法名
。例如,您的檔案名稱為index.js
或index.mjs
,方法名為handler
,則請求處理常式為index.handler
。
關於FC函數的具體定義和相關操作,請參見建立事件函數。
請求處理常式的具體配置均需符合Function Compute平台的配置規範。配置規範因請求處理常式類型而異。
Handler簽名
Function Compute從Node.js 18運行時開始支援ECMAScript(ES)模組。在此之前(Node.js 16及以前的版本),Function Compute僅支援使用CommonJS 模組。詳情請參見將請求處理常式指定為ES模組。
一個簡單的Event Handler簽名定義如下。
Node.js 18或Node.js 20
ES模組
當前範例程式碼支援一鍵部署,您可以直接在Function ComputeFC中一鍵部署本代碼。start-fc3-nodejs-es
// index.mjs
export const handler = async (event, context) => {
console.log("receive event: \n" + event);
return "Hello World!";
};
CommonJS模組
// index.js
exports.handler = async function(event, context) {
console.log("receive event: \n" + event);
return "Hello World!";
};
Node.js 16及以下版本
// index.js
exports.handler = async function(event, context, callback) {
console.log("event: \n" + event);
callback(null, 'hello world');
};
以上範例程式碼解析如下:
handler
是方法名稱,與Function Compute控制台配置的請求處理常式相對應。例如,建立函數時指定的請求處理常式為index.handler
,那麼Function Compute會去載入index.js
中定義的handler
函數,並從這裡開始執行。
Function Compute運行時會將請求參數傳遞到請求處理常式中,第一個參數是event
對象,包含請求的承載資訊,event
對象是Buffer類型,您可以將其轉換成所需要的物件類型。第二個參數是 context
對象,提供在調用時的運行上下文資訊。更多資訊,請參見上下文。
使用Node.js 18及以上版本的運行時環境時,建議您使用Async/Await功能,而不是使用回呼函數
callback
。Function Compute會根據傳回值的類型對返回結果做相應轉換。
Buffer類型:不轉換,原樣返回。
Object類型:轉換為JSON格式後返回。
其他類型:轉換為字串後返回。
Async/Await
使用Node.js 18及以上版本的運行時環境時,建議您使用Async/Await方式來實現。Async/Await是一種簡潔、易讀的Node.js非同步代碼編寫方式,無需嵌套回調或鏈式調用。
如果您使用的Node.js 16及以下版本的運行時環境,則必須顯式使用回調方法 callback
發送響應,否則會出現請求逾時錯誤。
Async/Await方式與回呼函數callback
相比,有以下優點:
可讀性更好:Async/Await方式的代碼更加線性和同步,更易於理解和維護。它避免了回呼函數嵌套過深的情況,使代碼結構更清晰。
調試和錯誤處理更簡單:可以使用try-catch塊更方便地捕獲和處理非同步作業中的錯誤,錯誤堆棧更加清晰,可以更準確地追蹤錯誤發生的位置。
效率更高:回呼函數通常需要在代碼的不同部分之間切換。Async/Await方式可以減少環境切換的數量,從而提高代碼效率。
樣本一:解析JSON格式參數
範例程式碼
當您傳入JSON格式參數時,Function Compute會透傳參數內容,需要您在代碼中自行解析。下面是解析JSON格式事件的程式碼範例。
ES模組
此樣本僅支援運行在Node.js 18及以上版本的運行時環境。
export const handler = async (event, context) => {
var eventObj = JSON.parse(event.toString());
return eventObj['key'];
};
CommonJS模組
當前範例程式碼支援一鍵部署,您可以直接在Function ComputeFC中一鍵部署本代碼。start-fc3-nodejs-json
exports.handler = function(event, context, callback) {
var eventObj = JSON.parse(event.toString());
callback(null, eventObj['key']);
};
前提條件
已建立Node.js函數,具體操作,請參見建立事件函數。如果您需要將代碼指定為ES模組,建立函數時,運行環境需選擇Node.js 18或Node.js 20。
操作步驟
登入Function Compute控制台,在左側導覽列,單擊函數。
在頂部功能表列,選擇地區,然後在函數頁面,單擊目標函數。
在函數配置頁面,選擇代碼頁簽,在代碼編輯器中輸入上述範例程式碼,然後單擊部署代碼。
說明上述範例程式碼中函數的請求處理常式是
index.js
中的handler
方法。如果您的函數的請求處理常式配置不同,請擷取對應的檔案和方法進行更新。在代碼頁簽,單擊測試函數右側的表徵圖,從下拉式清單中選擇配置測試參數,輸入以下樣本測試參數,然後單擊確定。
{ "key": "value" }
單擊測試函數。
函數執行成功後,查看返回結果,您可以看到返回結果為
value
。
樣本二:通過臨時密鑰安全讀寫OSS的資源
範例程式碼
您可以使用Function Compute為您提供的臨時密鑰訪問Object Storage ServiceOSS,程式碼範例如下所示。
ES模組
此樣本僅支援運行在Node.js 18及以上版本的運行時環境。
// 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
}
};
程式碼範例解析:
context.credentials
:從 context 參數中擷取臨時密鑰,避免在代碼中寫入程式碼密碼等敏感資訊。myObj
:OSS對象名。Buffer.from('hello, fc', "utf-8")
: 上傳的對象內容。return "put object"
:上傳成功正常返回 "put object"。throw err
:上傳失敗時拋出異常。
CommonJS模組
當前範例程式碼支援一鍵部署,您可以直接在Function ComputeFC中一鍵部署本代碼。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);
});
};
範例程式碼解析如下:
context.credentials
:表示從context
參數中擷取臨時密鑰,避免在代碼中寫入程式碼密碼等敏感資訊。myObj
:OSS對象名稱。Buffer.from('hello, fc', "utf-8")
:上傳的對象的內容。callback(null, 'put object')
:上傳成功正常返回put object
。callback(err)
:上傳失敗時返回err
。
前提條件
為服務配置具有訪問Object Storage Service的許可權的角色。具體操作,請參見授予Function Compute訪問其他雲端服務的許可權。
建立運行環境為Node.js的函數。具體操作,請參見建立事件函數。如果您需要將代碼指定為ES模組,建立函數時,運行環境需選擇Node.js 18或Node.js 20。
操作步驟
登入Function Compute控制台,在左側導覽列,單擊函數。
在頂部功能表列,選擇地區,然後在函數頁面,單擊目標函數。
(可選)在目標函數的函數詳情頁簽,選擇代碼頁簽,然後在下方的WebIDE介面,依次選擇
開啟終端,執行以下命令安裝ali-oss依賴。npm install ali-oss --save
安裝完成後,在WebIDE介面左側代碼目錄可以看到產生了
node_modules
檔案夾,檔案夾內包含ali-oss
目錄以及其他依賴庫。在目標函數的函數詳情頁簽,選擇代碼頁簽,在下方的代碼編輯器中輸入上述範例程式碼,儲存並單擊部署代碼。
說明上述範例程式碼中函數的請求處理常式是
index.js
或index.mjs
檔案中的handler
方法。如果您的函數的請求處理常式配置不同,請擷取對應的檔案和方法進行更新。上述範例程式碼中
region
和bucket
需按照實際情況填寫。
單擊測試函數。
函數執行成功後,查看返回結果,您可以看到返回結果為
put object
。
樣本三:調用外部命令
您的Node.js程式也可以建立fork
進程,調用外部命令。例如,您可以使用child_process
模組調用Linux的ls -l
命令,輸出目前的目錄下的檔案清單。程式碼範例如下所示。
ES模組
此樣本僅支援運行在Node.js 18及以上版本的運行時環境。
'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模組
當前範例程式碼支援一鍵部署,您可以直接在Function ComputeFC中一鍵部署本代碼。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);
});
}
樣本四:使用HTTP觸發器調用函數
範例程式碼
使用HTTP觸發器提供的URL調用函數,函數程式碼範例如下。
如果HTTP觸發器的認證方式為無需認證,您可以直接使用Postman或Curl工具來調用函數。具體操作,請參見操作步驟。
如果HTTP觸發器的認證方式為簽名認證或JWT認證,請使用簽名方式或JWT認證方式來調用函數。具體操作,請參見認證鑒權。
關於HTTP觸發調用的請求負載格式和響應負載格式,請參見HTTP觸發器調用函數。
ES模組
此樣本僅支援運行在Node.js 18及以上版本的運行時環境。
'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模組
當前範例程式碼支援一鍵部署,您可以直接在Function ComputeFC中一鍵部署本代碼。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
});
}
前提條件
已使用上述樣本建立運行環境為Node.js的函數並建立HTTP觸發器。具體操作,請參見建立事件函數和配置HTTP觸發器並使用HTTP觸發。如果您需要將代碼指定為ES模組,建立函數時,運行環境需選擇Node.js 18或Node.js 20。
操作步驟
登入Function Compute控制台,在左側導覽列,單擊函數。
在頂部功能表列,選擇地區,然後在函數頁面,單擊目標函數。
在函數詳情頁面,單擊配置頁簽,然後再左側導覽列,單擊觸發器,在觸發器頁面擷取HTTP觸發器的公網訪問地址。
在Curl工具執行以下命令,調用函數。
curl -i "https://test-nodejs-dlgxxr****.cn-shanghai.fcapp.run" -d 'Hello World!'
以上命令中,
https://test-nodejs-dlgxxr****.cn-shanghai.fcapp.run
為擷取到的HTTP觸發器公網訪問地址。響應結果如下。
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
樣本五:使用HTTP觸發器下載檔案
範例程式碼
如果您想通過代碼返回一個圖片、壓縮包或二進位檔案,可以使用HTTP觸發器實現在函數代碼中返回,函數程式碼範例如下。
ES模組
此樣本僅支援運行在Node.js 18及以上版本的運行時環境。
// 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模組
// 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
});
}
};
前提條件
已使用上述樣本建立運行環境為Node.js的函數並建立HTTP觸發器。具體操作,請參見建立事件函數和配置HTTP觸發器並使用HTTP觸發。如果您需要將代碼指定為ES模組,建立函數時,運行環境需選擇Node.js 18或Node.js 20。
操作步驟
登入Function Compute控制台,在左側導覽列,單擊函數。
在頂部功能表列,選擇地區,然後在函數頁面,單擊目標函數。
在函數詳情頁面,選擇代碼頁簽,然後選擇
開啟終端視窗,執行命令npm install mime@2
安裝mime庫。安裝完成後,單擊部署代碼。在函數配置頁面的觸發器頁簽,擷取HTTP觸發器的公網訪問地址,複製URL到瀏覽器並斷行符號。
斷行符號後觸發器函數執行,執行成功後下載檔案到本地。