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されません。