executeAction
executeAction はアクションを実行する関数です。
アクションの実行結果の値をパラメーターの値として別のアクションを実行するなどのワークフローを作成できます。
executeAction関数経由でのアクションの実行でも、ログイン中のユーザーが実行権限を持っているか検証されます。
例外として、ユーザー自身は権限を持っていなくても、呼び出し元のJavaScriptアクションが許可されている場合には実行できます。
基本的な使い方
以下は、商品の画像ファイルを保存するアクションの例です。
最初にストレージへ画像ファイルをアップロードするアクションを実行し、その後保存したファイルのパスをDBへ保存するアクションを実行しています。
// executeAction関数をインポート
import { executeAction } from "@basemachina/action";
/** @type { import("@basemachina/action").Handler } */
export default async ({ id, image }) => {
// ①ストレージに画像ファイルをアップロード
const uploadResults = await executeAction("upload-product-image", {
id: id,
image: image,
});
// ②保存した画像ファイルのストレージのパスをDBに保存
const insertResults = await executeAction("insert-product-image", {
id: id,
// ①のアクションの結果の画像ファイルのパスを使用する
path: uploadResults[0].success.objectKey,
});
return insertResults[0].success;
};詳細なインターフェース
引数
| 引数名 | 型 | 必須 | 説明 | 例 |
|---|---|---|---|---|
actionId | string | ✓ | 実行するアクションのID、または識別子。 | c3hc2ii23akg0sokf9j0, get-user |
args | object | アクションを実行するための引数で、 キーがパラメータ名、値がパラメータに渡す値のオブジェクトです。 | { username: 'JohnDoe' } | |
options | object | アクションの実行オプションを指定するオブジェクトです。 | { throwOnFailure: true } |
なおパラメータの入力値の種類ごとにargsのプロパティの値に渡せる値の型は以下です。
| 入力値の種類 | 型 | 説明 | 例 |
|---|---|---|---|
| テキスト | string | - | { company_name: '株式会社ベースマキナ' } |
| 数値 | number | null | - | { user_id: 123 } |
| 日付 | Date | string | number | null | stringはDate型に変換できる値、numberはUnixTimestamp (秒)を入力してください。 | { created: '2023-01-01', updated: new Date(), deleted: 1609459200 } |
| ファイル | File | null | - | { upload_text: new File(['test'], 'test.txt', { type: 'text/plain' }) } |
| 真偽値 | boolean | - | { checked: true } |
| JSON値 | string | number | Date | null | JSON値の種類ごとに型が異なります。 テキストなら string | null、数値ならnumber | null、日付ならstring | number | Date | nullを渡せます。日付の場合 stringはDate型に変換できる値、numberはUnixTimestamp (秒)を入力してください。 | { company_name: '株式会社ベースマキナ', user_id: 123, created: '2023-01-01', deleted: null } |
| SQL | string | - | { query: 'SELECT * FROM users;' } |
| システム値 | string | - | { offset: '20' } |
| 配列 | Array | 各要素の種類の型は、各入力値の種類の型と同じです。 | { user_ids: [10, 11, 12] } |
| タプル | Array | 各要素の種類の型は、各入力値の種類の型と同じです。 | { id_and_name: [123, 'taro'] } |
options
| プロパティ名 | 型 | デフォルト | 説明 |
|---|---|---|---|
throwOnFailure | boolean | false | trueに設定すると、アクションの実行に失敗した場合にExecuteActionFailureErrorをcauseに持つエラーをthrowします。詳細はExecuteActionFailureErrorを参照してください。 |
戻り値
| プロパティ名 | 型 | 説明 | 例 |
|---|---|---|---|
results | Array | アクションの実行結果の配列。各要素にはsuccess と failure のプロパティが含まれます。 | [{"success":[{"id":1,"name":"山田太郎"}]}] |
アクションの実行失敗のハンドリング
パラメーターの型チェック、実行権限チェックなどのアクション実行の事前バリデーションおよび、システム起因のエラー以外でアクションの実行に失敗した場合、結果のfailureプロパティに失敗の内容が設定されます。
通常は、このプロパティの有無を確認することで、アクションの実行失敗をハンドリングできます。
基本的なハンドリングの例
以下は、failureプロパティを使った基本的なハンドリングの例です。
import { executeAction } from "@basemachina/action";
/** @type { import("@basemachina/action").Handler } */
export default async ({ id, image }) => {
const uploadResults = await executeAction("upload-product-image", {
id,
image,
});
// failureプロパティの有無を確認
if (uploadResults[0].failure) {
throw new Error("画像のアップロードに失敗しました");
}
return uploadResults[0].success;
};複数のアクションを実行する場合の課題
複数のアクションを順番に実行するワークフローにおいては、各アクションの実行後に毎回failureプロパティの確認が必要になります。
import { executeAction } from "@basemachina/action";
/** @type { import("@basemachina/action").Handler } */
export default async ({ id, image }) => {
// ①ストレージへの画像ファイルのアップロード
const uploadResults = await executeAction("upload-product-image", {
id,
image,
});
if (uploadResults[0].failure) {
throw new Error("画像のアップロードに失敗しました");
}
// ②DBへの画像ファイルのパスの保存
const insertResults = await executeAction("insert-product-image", {
id,
path: uploadResults[0].success.objectKey,
});
if (insertResults[0].failure) {
throw new Error("画像パスの保存に失敗しました");
}
return insertResults[0].success;
};throwOnFailureオプションでハンドリングを簡潔にする
上記のようなコードを冗長と感じる場合は、options引数のthrowOnFailureプロパティを活用できます。
throwOnFailureをtrueに設定することで、アクションの実行失敗時に自動的にエラーをthrowするため、毎回failureプロパティを確認する必要がなくなります。
上記の例でthrowOnFailureオプションを使用すると、以下のとおり簡潔に記述できます。
import { executeAction } from "@basemachina/action";
/** @type { import("@basemachina/action").Handler } */
export default async ({ id, image }) => {
// ①ストレージへの画像ファイルのアップロードに失敗した場合は自動的にエラーをthrow
const uploadResults = await executeAction(
"upload-product-image",
{ id, image },
{ throwOnFailure: true },
);
// ②DBへの画像ファイルのパスの保存に失敗した場合は自動的にエラーをthrow
const insertResults = await executeAction(
"insert-product-image",
{ id, path: uploadResults[0].success.objectKey },
{ throwOnFailure: true },
);
return insertResults[0].success;
};ExecuteActionFailureError
throwOnFailureオプションをtrueに設定した場合、アクションの実行失敗時にExecuteActionFailureErrorをcauseに持つエラーがthrowされます。
このエラーには、失敗した結果と、すべての実行結果(成功したものも含む)の両方が含まれます。
使用例: 画像アップロードの失敗理由の詳細を返す
画像をストレージにアップロードし、そのパスをDBへ保存するワークフローにおいて、画像のアップロードが失敗した場合に詳細な情報を構造化して返すケースを考えてみましょう。
import {
executeAction,
ExecuteActionFailureError,
ResultError,
} from "@basemachina/action";
/** @type { import("@basemachina/action").Handler } */
export default async ({ id, image }) => {
// ①ストレージに画像をアップロードする
const uploadedPath = await (async () => {
try {
const uploadResults = await executeAction(
"upload-product-image",
{ id, image },
{ throwOnFailure: true },
);
return uploadResults[0].success.objectKey;
} catch (err) {
if (err.cause instanceof ExecuteActionFailureError) {
throw new ResultError({
message: "画像のアップロードに失敗しました",
id,
errorDetail: err.cause.failureResult.failure,
});
}
throw err;
}
})();
// ②保存した画像ファイルのストレージのパスをDBに保存
const insertResults = await executeAction("insert-product-image", {
id,
path: uploadedPath,
});
return insertResults[0].success;
};このように、ExecuteActionFailureErrorとResultErrorを使うことで、詳細なエラー情報を構造化して返せます。
ResultErrorの詳細については、ResultErrorのドキュメントを参照してください。
ExecuteActionFailureErrorのプロパティ
| プロパティ名 | 型 | 説明 |
|---|---|---|
failureResult | Object | 失敗したアクションの結果。failureプロパティにエラー内容が含まれます。 |
results | Array | アクションのすべての実行結果の配列。成功した結果と失敗した結果の両方が含まれます。 |
failureResultは、results配列のなかで最初に失敗した結果と同じオブジェクトです。
注意事項
ExecuteActionFailureErrorはcauseプロパティに格納されているため、instanceofによる判定にはerr.causeを使用してください。- パラメーターの型チェック、実行権限チェックなどのアクション実行の事前バリデーションで失敗した場合は、
ExecuteActionFailureErrorを含むエラーはthrowされません。