PI Management - SwaggerからのAPIインポート、Functionsとの連携


目的

Azure API Managementの基本操作と、BackendにFunctionsを連携する方法を確認する

API Management インスタンスの作成

公式ドキュメント(Azure portal を使用して新しい Azure API Management サービス インスタンスを作成する
を参照
※API Management サービス インスタンスがオンラインになるまで20~30分程度かかる

API作成

Swaggerの用意

以下の適当なSwaggerファイルを用意

swagger.yaml
openapi: 3.0.1
info:
  description: 'REST API 定義'
  version: '1.0.0'
  title: restApi
paths:
  /:
    get:
      responses:
        200:
          description: 'OK'
        400:
          description: 'Bad Request'
  /api:
    get:
      responses:
        200:
          description: 'OK'
        400:
          description: 'Bad Request'

SwaggerからAPI のインポート

1.Azure portalで、API+Add APIOpenAPIを選択

2.Select a fileから用意したSwaggerファイルを選択

3.以下インポートが完了した状態

製品にAPIの追加

※今回はデフォルトで用意されているStarterを使用する

1.Azure portalで、製品Starterを選択

2.+APIの追加 → 作成したAPIにチェックを入れ選択をクリック

Backend設定

httpbinを使用する

HTTPリクエストに対して簡単な応答を返してくれるサービスhttpbinをBackendに設定する
https://httpbin.org/getに対してリクエストを送信すると、送信したパラメータやヘッダー情報がレスポンスされる

1.Azure portalで、Design/のAPIを選択
2.Backendの編集ボタンを選択

3.Overrideにチェックを入れ、Service URLhttps://httpbin.org/getを入力
4.Saveをクリック

Functionsを使用する

関数作成

トリガーがHTTPの関数を作成する

関数はデフォルトのまま使用

import logging

import azure.functions as func


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
    else:
        return func.HttpResponse(
             "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
             status_code=200
        )

FunctionsからAPIをインポートする

1.Azure portalで、作成したAPIの右にある設定 → importを選択

2.Function Appを選択

3.*関数アプリ → 作成した関数アプリを選択し選択をクリック

3.選択をクリック

4.以下インポート結果

ルーティング設定

Azure Functions の HTTP トリガー

function.jsonroute を追記することでURLを設定できる

function.json
{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get"
      ],
      "route": "data1/{id:int}"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

以下のroute設定を行った場合、

HttpTrigger1:route記載なし
HttpTrigger2:"data1/{id:int}"
HttpTrigger3:"{group}/{id:int}"

API Management にインポートすると以下のようにURLが設定される



テスト&トラブルシューティング

1.Azure portalで、Test/のAPIを選択 → Sendをクリック

2.200 OKが返ってくることを確認
※外部からAPIをコールする場合はヘッダにOcp-Apim-Subscription-Keyを指定する必要がある

BackendがFunctionsのHttpTrigger1のAPIでも同様、関数でレスポンスしている文字列が取得できている

APIのレスポンスが空になる


Testを行うとレスポンスが200 OKだが、レスポンスのbodyが空(content-length: 0)となる現象が発生した
※一度APIを削除後、再度Swaggerからインポートし直したところ発生しなくなった

症状と解決法について公式ドキュメント(AzureAPIが空白の応答を返しています)に記載があった

解決方法(転送要求ポリシーを設定する)

転送要求ポリシーが設定されていない場合、リクエストはBackendサービスに送信されず、即正常完了を応答する
以下のようにポリシーにforward-requestを追加する

<!-- api level -->
<policies>
    <inbound>
        <base/>
    </inbound>
    <backend>
        <forward-request timeout="60"/>
    </backend>
    <outbound>
        <base/>
    </outbound>
</policies>

ポリシーは以下の</>から編集する