次の方法で共有


パート 7: メイン アプリケーション API エンドポイント

前のパート: メイン アプリのスタートアップ コード

API の /api/v1/getcode アプリの URL パスは、英数字コードとタイムスタンプを含む JSON 応答を生成します。

まず、@app.route デコレーターは、get_code 関数が /api/v1/getcode URL への要求を処理することを Flask に通知します。

@app.route('/api/v1/getcode', methods=['GET'])
def get_code():

次に、アプリはサード パーティ製の API を呼び出します。URL は number_urlにあり、ヘッダーのキー コンテナーから取得するアクセス キーを提供します。

headers = {
    'Content-Type': 'application/json',
    'x-functions-key': access_key
    }

r = requests.get(url = number_url, headers = headers)

if (r.status_code != 200):       
    return "Could not get you a code.", r.status_code

サード パーティ製 API の例は、Azure Functions のサーバーレス環境にデプロイされます。 ヘッダーの x-functions-key プロパティは、Azure Functions がヘッダーにアクセス キーを表示する方法です。 詳細については、「Azure Functions HTTP トリガーの - 承認キーの」を参照してください。 何らかの理由で API の呼び出しが失敗した場合、エラー メッセージと状態コードが返されます。

API 呼び出しが成功し、数値が返されると仮定すると、アプリはその数値とランダムな文字 (独自の random_char 関数を使用) を使用して、より複雑なコードを構築します。

data = r.json()
chars1 = random_char(3)
chars2 = random_char(3)
code_value = f"{chars1}-{data['value']}-{chars2}"
code = { "code": code_value, "timestamp" : str(datetime.utcnow()) }

ここで code 変数には、コード値とタイムスタンプを含む、アプリの API の完全な JSON 応答が含まれています。 応答の例は {"code":"ojE-161-pTv","timestamp":"2020-04-15 16:54:48.816549"}です。

ただし、その応答を返す前に、Queue クライアントの send_message メソッドを使用して、ストレージ キューにメッセージを書き込みます。

queue_client.send_message(code)

return jsonify(code)

キュー メッセージの処理

キューに格納されているメッセージは、 Azure portal、Azure CLI コマンド az storage message get 、または Azure Storage Explorer を使用して表示および管理できます。 サンプル リポジトリには、アプリ エンドポイントからコードを要求し、メッセージ キューを確認するためのスクリプト (test.cmdtest.sh) が含まれています。 az storage message clear コマンドを使用してキューをクリアするスクリプトもあります。

通常、この例のようなアプリには、キューからメッセージを非同期的にプルして処理を進める別のプロセスがあります。 前述のように、この API エンドポイントによって生成される応答は、2 要素ユーザー認証を使用してアプリ内の別の場所で使用される場合があります。 その場合、アプリは一定期間 (たとえば 10 分) 後にコードを無効にする必要があります。 このタスクを実行する簡単な方法は、有効な 2 要素認証コードのテーブルを維持することです。このコードは、ユーザーのサインイン手順で使用されます。 その後、アプリには、次のロジック (擬似コード) を使用した単純なキュー監視プロセスが含まれます。

pull a message from the queue and retrieve the code.

if (code is already in the table):
    remove the code from the table, thereby invalidating it
else:
    add the code to the table, making it valid
    call queue_client.send_message(code, visibility_timeout=600)

この擬似コードは、メッセージがキューに表示されるまでの秒数を指定する、send_message メソッドの省略可能な visibility_timeout パラメーターを使用します。 既定のタイムアウトは 0 であるため、API エンドポイントによって最初に書き込まれたメッセージは、キュー監視プロセスにすぐに表示されます。 その結果、そのプロセスは、それらをすぐに有効なコード テーブルに格納します。 プロセスはタイムアウトで同じメッセージをもう一度キューに入れ、10 分後にコードを再び受信します。この時点でテーブルから削除されます。

Azure Functions でのメイン アプリ API エンドポイントの実装

この記事で前に示したコードでは、Flask Web フレームワークを使用して API エンドポイントを作成します。 Flask は Web サーバーで実行する必要があるため、このようなコードは Azure App Service または仮想マシンにデプロイする必要があります。

代替デプロイ オプションは、Azure Functions のサーバーレス環境です。 この場合、すべてのスタートアップ コードと API エンドポイント コードは、HTTP トリガーにバインドされているのと同じ関数内に含まれます。 App Service と同様に、関数アプリケーション設定 を使用して、コードの環境変数を作成します。

実装の 1 つが簡単になるのは、Queue Storage を使用した認証です。 キューの URL と資格情報オブジェクトを使用して QueueClient オブジェクトを取得する代わりに、関数の キュー ストレージ バインド を作成します。 バインドは、バックグラウンドですべての認証を処理します。 このようなバインディングを使用すると、関数には、すぐに使用できるクライアント オブジェクトがパラメーターとして指定されます。 詳細とコード例については、「Azure Functions を Azure Queue Storageに接続する」を参照してください。

次の手順

このチュートリアルでは、アプリがマネージド ID を使用して他の Azure サービスと認証する方法と、アプリが Azure Key Vault を使用してサードパーティ API に必要な他のシークレットを格納する方法について説明しました。

Azure Key Vault と Azure Storage でここで示したのと同じパターンが、他のすべての Azure サービスに適用されます。 重要な手順は、Azure portal 上のサービスのページ内または Azure CLI を使用して、アプリに適切なロールを割り当てることです。 (「Azure ロールを割り当てる方法」を参照してください)。 サービスのドキュメントを確認して、他のアクセス ポリシーを構成する必要があるかどうかを確認してください。

ローカル開発に使用しているサービス プリンシパルに同じロールとアクセス ポリシーを割り当てる必要があることを忘れないでください。

つまり、このチュートリアルを完了すると、任意の数の他の Azure サービスと任意の数の他の外部サービスに知識を適用できます。

このチュートリアルで触れていない 1 つの主題は、ユーザーの認証です。 Web アプリのこの領域を調べるには、「Azure App Serviceでユーザーをエンド ツー エンドで認証および承認する」から始めます。

関連項目