---
pkg: '@nocobase/plugin-workflow-request-interceptor'
---

# 操作前イベント

## はじめに

操作前イベントプラグインは、作成、更新、削除といった操作のリクエストが送信された後、実際に処理される前にトリガーされるインターセプト機能を提供します。

トリガーされたワークフロー内で「ワークフローを終了」ノードが実行された場合、または他のノードの実行が失敗した場合（エラーや未完了など）、そのフォーム操作はインターセプトされます。それ以外の場合は、予定された操作が正常に実行されます。

「応答メッセージ」ノードと組み合わせることで、クライアントに返される応答メッセージを設定し、適切な情報を提示できます。操作前イベントは、クライアントから送信される作成、更新、削除などの操作リクエストを承認またはインターセプトするためのビジネスバリデーションやロジックチェックに利用できます。

## トリガーの設定

### トリガーの作成

ワークフローを作成する際、タイプとして「操作前イベント」を選択します。

![Create Before Action Event](https://static-docs.nocobase.com/2add03f2bdb0a836baae5fe9864fc4b6.png)

### コレクションの選択

インターセプトワークフローのトリガーで最初に設定するのは、操作に対応するコレクションです。

![Interceptor Event Configuration_Collection](https://static-docs.nocobase.com/8f7122caca8159d334cf776f838d53d6.png)

次にインターセプトモードを選択します。このワークフローにバインドされた操作ボタンのみをインターセプトするか、またはこのコレクションの選択されたすべての操作をインターセプトするか（どのフォームから来たかに関わらず、対応するワークフローをバインドする必要もありません）を選択できます。

### インターセプトモード

![Interceptor Event Configuration_Interception Mode](https://static-docs.nocobase.com/145a7f7c3ba440bb6ca93a5ee84f16e2.png)

現在サポートされている操作タイプは「作成」、「更新」、「削除」です。複数の操作タイプを同時に選択できます。

## 操作の設定

トリガー設定で「このワークフローにバインドされたフォームが送信された場合にのみインターセプトをトリガー」モードを選択した場合、フォーム画面に戻り、対応する操作ボタンにこのワークフローをバインドする必要があります。

![Add Order_Bind Workflow](https://static-docs.nocobase.com/bae3931e60f9bcc51bbc222e40e891e5.png)

ワークフローのバインド設定で対応するワークフローを選択します。通常、トリガーデータのコンテキストはデフォルトの「フォームデータ全体」で十分です。

![Select Workflow to Bind](https://static-docs.nocobase.com/78e2f023029bd570c91ee4cd19b7a0a7.png)

:::info{title=ヒント}
操作前イベントにバインドできるボタンは、現在、新規作成または更新フォームの「送信」（または「保存」）、「データ更新」、「削除」ボタンのみです。「ワークフローをトリガー」ボタンはサポートされていません（このボタンは「操作後イベント」にのみバインドできます）。
:::

## インターセプトの条件

「操作前イベント」では、対応する操作がインターセプトされる2つの条件があります。

1.  ワークフローが任意の「ワークフローを終了」ノードに到達した場合。前述の使用説明と同様に、トリガーされたワークフローのデータが「条件判断」ノードで事前に設定された条件を満たさない場合、「いいえ」の分岐に進み、「ワークフローを終了」ノードが実行されます。この時点でワークフローは終了し、リクエストされた操作はインターセプトされます。
2.  ワークフロー内の任意のノードの実行が失敗した場合。ノードの実行エラーやその他の例外状況を含みます。この場合、ワークフローは対応するステータスで終了し、リクエストされた操作もインターセプトされます。例えば、ワークフローが「HTTPリクエスト」を通じて外部データを呼び出す際に、リクエストが失敗した場合、ワークフローは失敗ステータスで終了すると同時に、対応する操作リクエストもインターセプトされます。

インターセプト条件が満たされると、対応する操作は実行されなくなります。例えば、注文の送信がインターセプトされた場合、対応する注文データは作成されません。

## 対応する操作の関連パラメーター

「操作前イベント」タイプのワークフローでは、異なる操作に対して、トリガーからの異なるデータがワークフロー内で変数として使用できます。

| 操作タイプ \ 変数          | 「操作者」 | 「操作者ロールID」 | 操作パラメーター：「ID」 | 操作パラメーター：「送信されたデータオブジェクト」 |
| -------------------------- | -------- | ------------------ | ---------------------- | -------------------------------------------------- |
| レコードの作成             | ✓        | ✓                  | -                      | ✓                                                  |
| レコードの更新             | ✓        | ✓                  | ✓                      | ✓                                                  |
| 単一または複数のレコードの削除 | ✓        | ✓                  | ✓                      | -                                                  |

:::info{title=ヒント}
操作前イベントの変数「トリガーデータ / 操作パラメーター / 送信されたデータオブジェクト」は、データベース内の実際のデータではなく、操作で送信された関連パラメーターにすぎません。データベース内の実際のデータが必要な場合は、ワークフロー内で「データクエリ」ノードを使用して関連データをクエリする必要があります。

また、削除操作の場合、単一レコードを対象とする場合、操作パラメーターの「ID」は単一の値ですが、複数レコードを対象とする場合は配列になります。
:::

## 応答メッセージの出力

トリガーを設定した後、ワークフロー内で関連する判断ロジックをカスタマイズできます。通常、「条件判断」ノードの分岐モードを使用し、特定のビジネス条件の判断結果に基づいて、「ワークフローを終了」するかどうかを決定し、事前に設定された「応答メッセージ」を返します。

![Interceptor Workflow Configuration](https://static-docs.nocobase.com/cfddda5d8012fd3d0ca09f04ea610539.png)

これで、対応するワークフローの設定が完了しました。次に、ワークフローの条件ノードで設定された条件を満たさないデータを送信して、インターセプターのインターセプトロジックをトリガーしてみてください。そうすると、返される応答メッセージを確認できます。

![Error Response Message](https://static-docs.nocobase.com/06bd4a6b6ec499c853f0c39987f63a6a.png)

### 応答メッセージのステータス

「ワークフローを終了」ノードが「成功」ステータスで終了するように設定されており、このノードが実行された場合、その操作のリクエストは引き続きインターセプトされますが、返される応答メッセージは「成功」（「エラー」ではなく）ステータスで表示されます。

![Success Status Response Message](https://static-docs.nocobase.com/9559bbf56067144759451294b18c790e.png)

## 例

上記の基本的な使用説明を組み合わせ、ここでは「注文送信」シナリオを例にとります。ユーザーが注文を送信する際、選択されたすべての製品の在庫を検証する必要があるとします。選択されたいずれかの製品の在庫が不足している場合、注文の送信はインターセプトされ、対応するプロンプトメッセージが返されます。すべての製品の在庫が十分になるまで各製品をループしてチェックし、その時点で処理を進め、ユーザーの注文データを作成します。

その他の手順は説明と同じです。ただし、1つの注文が複数の製品を対象とするため、データモデリングで「注文」<-- M:1 -- 「注文詳細」-- 1:M --> 「製品」という多対多のリレーションシップを追加するだけでなく、「操作前イベント」ワークフローに「ループ」ノードを追加し、各製品の在庫が十分であるかを繰り返しチェックする必要があります。

![Example_Loop Check Workflow](https://static-docs.nocobase.com/8307de47d5629595ab6cf00f8aa898e3.png)

ループの対象は、送信された注文データ内の「注文詳細」配列として選択します。

![Example_Loop Object Configuration](https://static-docs.nocobase.com/ed662b54cc1f5425e2b472053f89baba.png)

ループ内の条件判断ノードは、現在ループ中の製品オブジェクトの在庫が十分であるかを判断するために使用されます。

![Example_Condition in Loop](https://static-docs.nocobase.com/4af91112934b0a04a4ce55e657c0833b.png)

その他の設定は基本的な使用方法と同じです。最終的に注文が送信される際、いずれかの製品の在庫が不足している場合、注文の送信はインターセプトされ、対応するプロンプトメッセージが返されます。テスト時には、1つの注文で複数の製品を送信してみてください。そのうち1つの製品の在庫が不足しており、もう1つの製品の在庫が十分である場合、返される応答メッセージを確認できます。

![Example_Response Message after Submission](https://static-docs.nocobase.com/dd9e81084aa237bda0241d399ac19270.png)

ご覧のとおり、応答メッセージでは最初の製品「iPhone 15 Pro」の在庫不足は示されておらず、2番目の製品「iPhone 14 Pro」の在庫不足のみが示されています。これは、ループ内で最初の製品の在庫が十分であったためインターセプトされず、2番目の製品の在庫が不足していたため、注文の送信がインターセプトされたためです。

## 外部からの呼び出し

操作前イベント自体はリクエスト処理フェーズに組み込まれているため、HTTP API呼び出しによるトリガーもサポートしています。

操作ボタンにローカルでバインドされたワークフローの場合、次のように呼び出すことができます（`posts` コレクションの作成ボタンを例に説明します）。

```bash
curl -X POST -H 'Authorization: Bearer <your token>' -H 'X-Role: <roleName>' -d \
  '{
    "title": "Hello, world!",
    "content": "This is a test post."
  }'
  "http://localhost:3000/api/posts:create?triggerWorkflows=workflowKey"
```

ここで、URLパラメーター `triggerWorkflows` はワークフローのキーであり、複数のワークフローキーはカンマで区切ります。このキーは、ワークフローキャンバス上部のワークフロー名にマウスカーソルを合わせると取得できます。

![Workflow_Key_View_Method](https://static-docs.nocobase.com/20240426135108.png)

上記の呼び出しが実行されると、対応する `posts` コレクションの操作前イベントがトリガーされます。対応するワークフローが同期的に処理された後、データは正常に作成され、返されます。

設定されたワークフローが「終了ノード」に到達した場合、インターフェース操作のロジックと同じで、リクエストはインターセプトされ、データは作成されません。終了ノードのステータスが失敗に設定されている場合、返される応答ステータスコードは `400` であり、成功時は `200` です。

終了ノードの前に「応答メッセージ」ノードも設定されている場合、生成されたメッセージも応答結果で返されます。エラー時の構造は次のとおりです。

```json
{
  "errors": [
    {
      "message": "message from 'Response message' node"
    }
  ]
}
```

「終了ノード」が成功に設定されている場合のメッセージ構造は次のとおりです。

```json
{
  "messages": [
    {
      "message": "message from 'Response message' node"
    }
  ]
}
```

:::info{title=ヒント}
ワークフローには複数の「応答メッセージ」ノードを追加できるため、返されるメッセージのデータ構造は配列になります。
:::

操作前イベントがグローバルモードで設定されている場合、HTTP APIを呼び出す際にURLパラメーター `triggerWorkflows` を使用して対応するワークフローを指定する必要はありません。対応するコレクション操作を直接呼び出すだけでトリガーされます。

```bash
curl -X POST -H 'Authorization: Bearer <your token>' -H 'X-Role: <roleName>' -d \
  '{
    "title": "Hello, world!",
    "content": "This is a test post."
  }'
  "http://localhost:3000/api/posts:create"
```

:::info{title=ヒント}
HTTP API呼び出しを通じて操作前イベントをトリガーする際、ワークフローの有効化状態とコレクション設定が一致しているかどうかに注意してください。そうしないと、呼び出しが成功しないか、エラーが発生する可能性があります。
:::