Azure ロジックアプリのカスタムAPIとPower Appsのカスタムコネクタ


## Logic AppをつかっているとREST APIから、カスタムAPIをつくることがあるかも

Logic AppをつかっているとREST APIから、カスタムAPIをつくることがあるかもしれません。
おそらく以下のドキュメントにたどり着くでしょう。

https://docs.microsoft.com/ja-jp/connectors/custom-connectors/

さすがMS。ドキュメントにはしっかり書いてあります。
書いてありますが、Power PlatformとAzureとどっちのことを言っているのか、混乱します。


Azureで作った場合はカスタムAPI(Microsoft.Web/CustomApis)ですが、Power Platformでつくったものはカスタムコネクタ(ManagedApi)となります。

AzureからはカスタムAPIを作成することができますし、ManagedApiを使用することができます。
カスタムAPIとカスタムコネクタで何がちがうのか?
実際に作ってみると全く違うものであることが分かりますし、できることが結構違います。
しかし、ドキュメントを読むだけで違いがわかるようになるのは難しいと思います。

この文書は備忘録兼苛立ちを書きなぐった文章です。
誰かの参考になるかもしれませんが、広く人の役に立つことは目指しては書いていません。


## きっかけ

とあるサービスのAPIに対してLogic Appを使って定期的にアクセスするということを実現しようとしました。
APIは大きいものではなかったので、自分でswaggerファイルを書き、カスタムAPIを作成してみようと思い立ったのが発端です。

この記事ではサンプルとして以下のswagger.jsonを使います。
ポイントはsecurityおよびSecurityDefinitionです。

アカウントをidとしてクエリパラメータに、APIキーをX-API-Keyとしてヘッダに埋める形です。
これはSwaggerの記述としては正しい記述です。

下の手順を実施して、Swagger Editorで実行してみましょう

1. Swagger Editor ( <https://editor.swagger.io> ) を開きます。
1. 下のswagger.jsonを貼り付けます。
1. webhook.siteを別タブで開きます
1. 新しく発行されたパスをコピーします。 Swagger Editorに戻り　/219a2902-17ef-4921-82fc-23e97f804e49 を書き換えます。
1. webhook.siteに戻り、CORS Headersを有効にします
1. Editを開いて Response Bodyに `{}` を入力します 
1. Swagger Editor にもどり、Authorizeを押します。account / token に 適当な値を入力してください
1. APIを実行します
1. APIの実行が終わり、webhook.siteでクエリパラメータにidが、ヘッダーにX-API-Keyがあるのが確認できるはずです。

```json
{
  "swagger": "2.0",
  "info": {
    "version": "1.0.0",
    "title": "Azure Custom Connector API",
    "description": "This API uses both account and token."
  },
  "host": "webhook.site",
  "schemes": [
    "https"
  ],
  "paths": {
    "/219a2902-17ef-4921-82fc-23e97f804e49": {
      "get": {
        "summary": "空のJSONを返す",
        "description": "空のJSONを返す",
        "operationId": "empty",
        "produces": [
          "application/json"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "fixed response"
          }
        }
      }
    }
  },
  "security": [
    {
      "account": [],
      "token": []
    }
  ],
  "securityDefinitions": {
    "account": {
      "type": "apiKey",
      "name": "id",
      "in": "query"
    },
    "token": {
      "type": "apiKey",
      "name": "X-API-Key",
      "in": "header"
    }
  }
}
```

## swagger.jsonでsecurityの複数指定に対応していない

先ほど書いた通り、このswagger.jsonは正しく記述できています。実際、Swagger Editorで動かすと期待通りに動きます。

しかし、これをカスタムAPIを作成のために使用しようとするとうまく作ることができません。
実はAzure カスタムAPIでは securityの複数指定に対応していないからです。

更に面倒なことにカスタムAPI作成する際swagger.jsonを編集することができるのですが、その際Swagger Editorを確認に使用しており、そこでは securityの複数指定に対応した動きをします。
またSwagger Editorで修正して保存するとsecurityのところが勝手に書き換わって保存されます。
びっくりします。これが開発者に混乱を招きます。

swagger.jsonでsecurityの複数指定に対応していないことはドキュメントには書いてありません。
ちなみに、Power Platformのforumに行くと対応していないとMSの人が回答していました。
細かいですが Azureのフォーラムではありません。

ではPower Platformのカスタムコネクタではどうでしょうか?
こちらもswagger.jsonからの定義から作るとうまくいきません。しかし、カスタムコネクタを作成して作る場合は、ポリシーテンプレートという機能を使って、期待通りの動作のコネクタを作ることができます。
ポリシーテンプレートとはコネクションから値を取得して、ヘッダ、クエリ、ホストなどの値を動的に設定する機能です。
コネクションはコネクタが使用する秘匿情報を保存しておくものです。カスタムコネクタ内で定義します。
そう、そして先ほどのフォーラムでは Power Platformでポリシーテンプレートを使うとできることは教えてくれません。

カスタムコネクタとカスタムAPIの違いは大きいです。
例えば契約毎にサブドメインを発行するようなタイプのSaaSが公式コネクタを作成する場合はPower Platformで作らなければうまく作れません。