Node.js ハンドラを使用して、イベントに応答し、ビジネスロジックを実行できます。このトピックでは、Node.js ハンドラの概念と構造について説明し、例を示します。
ハンドラとは
FC 関数のハンドラは、ご利用の関数コード内でリクエストを処理するメソッドです。FC 関数が呼び出されると、Function Compute は設定されたハンドラを実行してリクエストを処理します。ハンドラは、Function Compute コンソールの ハンドラー パラメーターを使用して設定できます。
Node.js の FC 関数では、ハンドラのフォーマットは filename.methodName です。たとえば、ファイル名が index.js または index.mjs で、メソッド名が handler の場合、ハンドラは index.handler となります。
FC 関数および関連操作の詳細については、「イベントトリガー関数の作成」をご参照ください。
ハンドラの設定は、Function Compute の設定仕様に準拠する必要があります。設定仕様はハンドラのタイプによって異なります。
ハンドラシグネチャ
Function Compute は、Node.js 18 ランタイムから ECMAScript (ES) モジュールをサポートしています。それ以前 (Node.js 16 以前のバージョン) では、Function Compute は CommonJS モジュールのみをサポートしていました。詳細については、「ES モジュールとしてのハンドラの指定」をご参照ください。
シンプルなイベントハンドラのシグネチャは次のとおりです。
Node.js 18 または Node.js 20
ES モジュール
このサンプルコードはワンクリックデプロイをサポートしています。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 モジュール
// 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 型であり、必要なオブジェクトタイプに変換できます。2 番目のパラメーターは context オブジェクトで、呼び出しのランタイムコンテキスト情報を提供します。詳細については、「コンテキスト」をご参照ください。
Node.js 18 以降のランタイムを使用する場合、
callbackの代わりに Async/Await 機能を使用してください。Function Compute は、返された結果をそのタイプに基づいて変換します。
Buffer 型:そのまま返されます。
オブジェクトタイプ: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アプローチは、コンテキストスイッチの数を減らし、コードの効率を向上させます。
例 1:JSON 形式のパラメーターの解析
サンプルコード
Function Compute は JSON 形式のパラメーターを直接関数に渡します。これらのパラメーターをコードで解析する必要があります。次のコードは、JSON 形式のイベントを解析する方法を示しています。
ES モジュール
この例は、Node.js 18 以降のランタイムでのみサポートされています。
export const handler = async (event, context) => {
var eventObj = JSON.parse(event.toString());
return eventObj['key'];
};
CommonJS モジュール
このサンプルコードはワンクリックデプロイをサポートしています。このコードをワンクリックで Function Compute (FC) にデプロイできます。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メソッドです。関数のハンドラが異なる設定になっている場合は、対応するファイルとメソッドを更新してください。コード タブで、関数のテスト の右側にある
アイコンをクリックします。ドロップダウンリストから テストパラメーターの設定 を選択します。次のサンプルテストパラメーターを入力し、OK をクリックします。{ "key": "value" }関数のテスト をクリックします。
関数が正常に実行された後、応答を確認します。応答は
valueです。
例 2:一時的な AccessKey ペアを使用した OSS リソースの安全な読み書き
サンプルコード
Function Compute が提供する一時的な AccessKey ペアを使用して、Object Storage Service (OSS) にアクセスします。次のコードは一例です。
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:コンテキストパラメーターから一時的な AccessKey ペアを取得します。これにより、パスワードなどの機密情報をコードにハードコーディングすることを回避できます。myObj:OSS オブジェクトの名前です。Buffer.from('hello, fc', "utf-8"):アップロードするオブジェクトのコンテンツです。return "put object":アップロードが成功した場合、put objectが返されます。throw err:アップロードが失敗した場合、例外がスローされます。
CommonJS モジュール
このサンプルコードはワンクリックデプロイをサポートしています。このコードをワンクリックで Function Compute (FC) にデプロイします。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パラメーターから一時的な AccessKey ペアを取得します。これにより、パスワードなどの機密情報をコードにハードコーディングすることを回避できます。myObj:OSS オブジェクトの名前です。Buffer.from('hello, fc', "utf-8"):アップロードするオブジェクトのコンテンツです。callback(null, 'put object'):アップロードが成功した場合、put objectが返されます。callback(err):アップロードが失敗した場合、errが返されます。
前提条件
OSS にアクセスする権限を持つサービスロールを設定します。詳細については、「関数ロールを使用して 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です。
例 3:外部コマンドの呼び出し
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 Compute (FC) にデプロイできます。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);
});
}例 4:HTTP トリガーを使用した関数の呼び出し
サンプルコード
HTTP トリガーによって提供される URL を使用して関数を呼び出します。次のコードは一例です。
HTTP トリガーの 認証方法 が 認証不要 に設定されている場合、Postman または curl コマンドを使用して関数を呼び出します。詳細については、「操作手順」をご参照ください。
HTTP トリガーの 認証方法 が 署名認証、JWT 認証または Bearer 認証 に設定されている場合、対応する認証方式を使用して関数を呼び出します。詳細については、「認証」をご参照ください。
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!';
// HTTP リクエストボディを取得
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 Compute (FC) にデプロイできます。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!';
// HTTP リクエストボディを取得
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 トリガーの設定」をご参照ください。コードを 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!
例 5: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 トリガーの設定」をご参照ください。コードを ES モジュールとして指定する場合は、関数の作成時にランタイムとして Node.js 18 または Node.js 20 を設定します。
操作手順
Function Compute コンソールにログインします。左側のナビゲーションウィンドウで、を選択します。
上部のナビゲーションバーで、リージョンを選択します。[関数] ページで、対象の関数をクリックします。
関数の詳細ページで、コード タブをクリックし、を選択してターミナルウィンドウを開きます。
npm install mime@2コマンドを実行して mime ライブラリをインストールします。インストールが完了したら、デプロイメントコード をクリックします。関数の トリガー タブで、HTTP トリガーの インターネットエンドポイント を取得します。URL をブラウザにコピーして Enter キーを押します。
Enter キーを押すと、関数がトリガーされます。関数が正常に実行されると、ファイルがローカルマシンにダウンロードされます。