【Azure Logic Apps】Requests トリガーのスキーマ定義と入力バリデーション

この記事は **[KDDIアジャイル開発センター（KAG） Advent Calendar 2024](https://qiita.com/advent-calendar/2024/kag)** 、20日目の記事です。

https://qiita.com/advent-calendar/2024/kag

## はじめに

お疲れ様です。KDDIアジャイル開発センター株式会社のはしもと（仮名）です。

表題の件、一生記憶に定着しないため、恐縮ですがこちらにて記事を認めさせていただければと存じます。

以上、何卒ご了承のほどよろしくお願いいたします。

## Azure Logic Apps について

Azure Logic Apps は、Azure クラウド上でワークフローを作成・自動化できるサービスです。
視覚的なデザイナーを使用してビジネスプロセスを簡単に構築でき、Azure の他サービスだけでなく、Microsoft Teams をはじめとする Microsoft 製品やサードパーティの SaaS など、様々なサービスと連携が可能です。

主な特徴
- ノーコードでワークフローを構築可能
- 200以上のコネクタを利用した他サービスとの連携
- スケーラブルな実行環境
- 豊富なトリガーとアクション

https://azure.microsoft.com/ja-jp/products/logic-apps

## Requestsトリガーの活用

Logic Apps でワークフローを作成する際は、ワークフローの呼び出し条件を制御する「トリガー」を設定する必要があります。

Requests トリガーは、Logic Apps をHTTPエンドポイントとして公開するための機能です。
これをトリガーに設定することで、ワークフローに対して自動的にHTTP URLが払い出されます。

https://learn.microsoft.com/ja-jp/azure/connectors/connectors-native-reqres?tabs=consumption

> この Request トリガーは、HTTPS 経由の受信要求のみを処理する、手動で呼び出し可能なエンドポイントを作成します。 

上記のように、決まったスケジューリングでの実行ではなく、オンデマンドでワークフローを実行したい場合にも Requests トリガーを使います。

## 基本的なスキーマ定義

リクエストボディをワークフローの入力として使用する場合は、事前にスキーマを定義します。
最もシンプルな文字列プロパティを持つスキーマ定義は以下のようになります。

```json
{
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        }
    }
}
```

常にスキーマに合致する入力であればよいですが、実際には次のようなケースが考えられます。
① 入力が空(null)
② `name` フィールドに指定された値が文字列ではない
③ 入力オブジェクトに `name` フィールドが含まれていない
④ 入力オブジェクトに `name` フィールド以外にも不要なフィールドが含まれている

「ワークフロー内にエラー時の処理はあるのに、そこへ到達する前にワークフローが失敗していた」なんてことも起こり得ます（起こった）

### 何が悲しいか

前述のスキーマ定義のみを設定した状態では、いずれのケースでもワークフローの呼び出しには成功してしまいます。
しかし、①、③の場合は `name` の値を取得しようとしたところでエラーになり、②は `name` に指定した値が任意のオブジェクトであっても文字列として処理されます。
④は、値の取得ではエラーになりませんが、しばしば事故のもとになるものなので望ましくないです。

そこでスキーマ定義を編集して、バリデーションをより厳格にします。

## バリデーション要件別の実装方法

:::note info
ここから先は、 Requests トリガーの設定項目 `Schema validation` を有効化したうえで進めます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463957/881062c2-b040-41c0-7b3e-bc154d990e7b.png)
:::

### 対策：ケース①、②（入力が空(null)、`name` フィールドに指定された値が文字列ではない）

ケース①、②は、上記 `Schema validation` の設定のみでバリデーションが機能し、ワークフローの実行が拒否されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463957/5a26a637-538f-9c8f-c76c-e04ca68baec4.png" width=300>

### 対策：ケース③（入力オブジェクトに `name` フィールドが含まれていない）

上の感じでケース③も検知してくれそうですが、これだけではスルーされてしまいます。
スキーマ定義に `required` を書くことで、指定のフィールドが含まれている場合のみワークフローの起動を許可します。

```diff_json
{
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        }
    },
+   "required": ["name"]
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463957/7866fb00-fa94-5a7a-c881-150bdc68b780.png" width=300>


### 対策：ケース④（入力オブジェクトに `name` フィールド以外にも不要なフィールドが含まれている）

更にスキーマ定義を修正します。
`"additionalProperties": false` を追加することで、スキーマ定義外のフィールドの入力を拒否し、ワークフローの実行も許可しません。

```diff_json
{
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        }
    },
    "required": ["name"],
+   "additionalProperties": false    
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463957/7541d22c-b3cb-fc85-8e43-0b72bce6b4ca.png" width=300>

おつです！

## まとめ

最近マイブームの Azure Logic Apps について、ワークフローを作成する中で毎回分からなくなるスキーマ定義とバリデーションの設定方法を確認しました。

[条件アクション](https://learn.microsoft.com/ja-jp/azure/logic-apps/logic-apps-control-flow-conditional-statement?tabs=consumption)や[スイッチアクション](https://learn.microsoft.com/ja-jp/azure/logic-apps/logic-apps-control-flow-switch-statement) でごりごり分岐ロジックを書けなくはないのですが、ワークフローをコード管理している身としては、ただでさえ複雑なワークフロー全体/アクションの定義量もなるべく減らしたいものです。

みんなも、スキーマ定義しっかり書こうな！

## 参考

https://qiita.com/ma2shita/items/d444f5e868716102ad82