PowerAutomate: はじめての JSON (JSON なんて怖くない) 

# 背景
プログラミング経験があまりないと、JSON って聞くだけで難しく感じます。
その上で、JSON 解析(ParseJSON) を、って説明すると、思考停止してそうだったので、ひとまず JSON についてまとめ。

ローコードとはいえ、いろんな事やりたくなると JSON は避けて通れないですよね

# 概要
- [JSON 概要](#json-概要)
- [JSON データ参照利用方法](#json-データ参照利用方法)
- [JSON 関連のコネクタと関数](#json-関連のコネクターとか関数)

# JSON 概要
https://techcommunity.microsoft.com/t5/microsoft-365-pnp-blog/introduction-to-json/ba-p/2049369

この記事が結構よさげなので、翻訳してでも見てみるといいかも。

## 念の為、軽く抜粋すると・・
JSON は、構造化データをテキストとして表現するための[標準形式](https://www.ecma-international.org/publications-and-standards/standards/ecma-404/) 
JSON データは、名前と値のペアを含む「オブジェクト」
```json:基本
{ "name": "Parker" }
```
複数のペアを入れるなら、カンマで区切る。最後にカンマは不要。順不同
```json:複数プロパティ
{
  "name": "Parker",
  "species": "porcupine"
}
```
文字列は、二重引用符で囲む。特殊文字は '\' を前につけることで無視させる（エスケープ）。
```json:特殊文字のエスケープ
{
  "name": "Parker",
  "action": "Parker says \"Sharing is caring\""
}
```
数値は、引用符不要
```json:数値
{
  "name": "Parker",
  "centimeters": 75,
  "kilograms": 28
}
```
ブールも引用符不要
```json:ブール
{
  "name": "Parker",
  "friendly": true,
  "bossy": false
}
```
オブジェクトを階層化（ネスト）することも可能
```json:階層化
{
  "name": "Parker",
  "classification": {
    "kingdom": "animalia"
  }
}
```
配列は、角括弧(square brackets) '[', ']' で囲み、カンマで区切る
```json:配列
{
  "name": "Parker",
  "nicknames": [
    "Quilled Crusader",
    "Spike"
  ]
}
```
オブジェクトも配列に出来ます
```json:オブジェクトを配列に
{
  "mascots": [
    {
      "name": "Bit"
    },
    {
      "name": "G-raffe"
    }
  ]
}
```
日付けは決まりがないが、マイクロソフト Graph API は、[ISO 8601](https://www.w3.org/TR/NOTE-datetime) 形式

:::note info
ISO 8601 は [wikipedia](https://ja.wikipedia.org/wiki/ISO_8601) の方が分かりやすいかも
:::

空の値は、null。配列なら空っぽで
```json:null
{
  "name": "Parker",
  "dnaSequence": null,
  "array": []
}
```
JSON スキーマの役割は、JSON 構造の定義で、Parse JSON で必須設定だが、最初は実データから自動生成でよい。



あとは、Qiita で検索してもたくさん出てくるので割愛

https://qiita.com/search?sort=&q=json+


# JSON データ参照（利用）方法
大きく分けて、２つ
1. [JSON 解析して動的コンテンツで指定](#json-解析して動的コンテンツで指定)
1. [直接指定](#直接指定)

## JSON 解析して動的コンテンツで指定
- JSON 解析(Parse JSON) コネクターを使って、動的コンテンツで使えるようにする。

これを利用することで、JSON 指定をしやすくなるので、通常はこれを利用するのが楽。

1. JSON 解析(Parse JSON) コネクター を追加
1. [Generate from sample] を開く
1. JSON の例をコピーしてから、[Done] 
1. Schema に JSON が生成される
    1. 必要に応じて以下などを修正
       - [項目が無い場合](https://qiita.com/baku2san/items/02fdde2f7360adc37996)<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/9b323b05-d2cb-5cb5-1a10-31a2bca95b3b.png)

そうすると、こんな感じで簡単に使えるようになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c87cffdd-9dba-6dee-d3ab-0f148d68fc5f.png)

## 直接指定
直接指定は、以下利点もあるので慣れてきたら試してみよう

- 慣れると便利
- 動的コンテンツだと選択できない場合でも、使える
    - 恐らく、入力対象の型に対する自動フィルターなので、キーワード検索で表示させられたりもするけど

:::note warn
null がある場合には '?' を追加しておくことでエラーを防ごう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/3b31695c-dcb9-24dd-02c6-836c8e734f5f.png)

こうしておくと、[empty()](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#empty) を使って null 確認も可能
:::

### 鍵括弧記述
プロパティ名を鍵括弧内に、引用符(Single Quote) で囲う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c2d4b86a-7fc9-600c-4a6d-88b191d14e99.png)

```bash:鍵括弧記述
variables('JSON Object')['name']
```

### 鍵括弧記述：ネスト＆配列
ネストしてる場合は、以下のように スラッシュ(Slash) で繋げて書くことも可能。
配列の場合は添え字指定（0 始まり）で、引用符不要（文字列ではないので）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/12dde68d-4041-f76e-cece-ac59399419b6.png)

```bash:ネスト＆配列
variables('JSON Object')['classification/nicknames'][0]
```

### プロパティ記述
カンマ(comma) でプロパティ名をそのまま繋げていくのでわかっていると書きやすくて便利
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/f4870d23-a146-52a3-4ba8-b811ec9a1c57.png)

```bash:プロパティをそのまま記述
variables('JSON Object').name
```

### プロパティ記述：ネスト＆配列
普通にカンマで繋げていくだけ。配列の場合は、鍵括弧記述と同じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/9cd0e116-5a04-fe87-3f8a-14fb574f7469.png)

```bash:プロパティ記述：ネスト＆配列
variables('JSON Object').classification.nicknames[0]
```

# Schema 定義エラーと対処
## Invalid type. Expected {type} but got Null.
このエラーは、Schema 定義を自動で行った場合によく起こるもので、null 許容型として定義して無い為です。

ゆえに、以下の "Name" のように複数定義するか、"Value" のようにしてやると行けた筈。
```json: null 許容定義
{
    "properties": {
        "Name": {
            "type": [
                "string",
                "null"
            ]
        },
        "Value": {}
    }
}
```

# JSON 関連のコネクターとか関数

## 関数
他にも、JSON 配列とした場合には、first(), skip(), etc. といった便利なものもありますよ

|名称とLink|MS Doc|補足|
|-|-|-|
|<a href="https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#json">json()</a>|<blockquote>**文字列または XML に対する JSON** (JavaScript Object Notation) 型の値、オブジェクト、またはオブジェクトの配列を返します。</blockquote>|文字列とかからオブジェクト化| 
|<a href="https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#addproperty">addProperty()</a>|<blockquote>JSON オブジェクトに**プロパティとその値または名前と値のペアを追加**し、更新されたオブジェクトを返します。 実行時にプロパティが既に存在する場合、関数は失敗し、エラーをスローします。</blockquote>|オブジェクトのプロパティ追加| 
|<a href="https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#removeproperty">removeProperty()</a>|<blockquote>**オブジェクトからプロパティを削除**し、更新されたオブジェクトを返します。 削除しようとしたプロパティが存在しない場合、この関数は元のオブジェクトを返します。</blockquote>|↑ の反対。削除| 
|<a href="https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#setProperty">setProperty()</a>|<blockquote>JSON **オブジェクトのプロパティの値を設定**し、更新されたオブジェクトを返します。 設定しようとしたプロパティが存在しない場合、そのプロパティがオブジェクトに追加されます。 新しいプロパティを追加するには、addProperty() 関数を使用します。</blockquote>|追加、削除、ときたら、更新| 
|<a href="https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#coalesce">coalesce()</a>|<blockquote>1 つまたは複数のパラメーターから、**最初の null 以外の値を返し**ます。 空の文字列、空の配列、空のオブジェクトは null ではありません。</blockquote>|null 時のデフォルト取得用など| 

## コネクター

|名称とLink|MS Doc|補足|
|-|-|-|
|Parse JSON|無いので、[説明ページ](https://techcommunity.microsoft.com/t5/microsoft-365-pnp-blog/how-to-use-parse-json-action-in-power-automate/ba-p/2121861)|動的コンテンツに無いときは、これを使って色々と取得するのでとても便利なので、絶対覚えよう|
|[作成(compose)](https://docs.microsoft.com/ja-jp/power-automate/data-operations#use-the-compose-action)|<blockquote> クラウド フローを設計するときに同じデータを複数回入力する必要がないようにするためのアクション</blockquote>|変数と似た感じ。変数は最上位で初期化が必要だが、こちらはその都度なので、一時的な受け皿に便利|
|[選択(select)](https://docs.microsoft.com/ja-jp/power-automate/data-operations#use-the-select-action)|<blockquote> 配列内のオブジェクトの形状を変換します。 たとえば、配列内の各オブジェクトの要素を追加、削除、名前変更できます。</blockquote>|これもとても便利。<br>・配列オブジェクト⇒新たなオブジェクト配列<br>・配列オブジェクト⇒素の配列<br>などが出来るので、必要な情報を集めてこれで結合って感じ。Adaptive Card の動的生成にもオススメ|

選択(select) や フィルター配列(Filter Array) の例は以下で

https://qiita.com/baku2san/items/39e7a40c1a1fb327362a

# JSON の確認方法
フローエディター上での確認もしやすくなってはいるものの、詳細に見たい場合は画面の広さや検索のしやすさなどからテキストエディターがお勧め

VS Code なら、以下でフォーマットしてみると見やすくなります
1. JSON ペースト
   （自動認識されない場合）
    1. CTRL + SHIFT + P 
    1. 言語モードの変更(Change Language Mode) を選択
    1. JSON を選択
1. ALT + SHIFT + F でフォーマット 

# あとがき
トリガーやコネクターの動きはドキュメントを見てもイメージが出来ないことがあるので、
一度動かして、JSON を確認してみるのが一番かな？と

習うより慣れろ、ですね

# keyword

what is JSON in Power Automate.