演習 - 入力バインディングを使用してデータを読み取る
ブックマーク検索サービスを作成したいとしましょう。 最初、サービスは読み取り専用です。 ユーザーがエントリを見つけたい場合に、エントリの ID を含む要求を送信すると、関数から URL を返します。 次のフローチャートはこの論理フローを示しています。
ユーザーがテキストを含む要求を送信すると、ブックマーク検索関数で、テキストがキーまたは ID であるブックマークを含むエントリをデータベース内で検索しようとします。 システムにより、エントリが見つかったかどうかを示す結果が返されます。
Azure 関数では、ブックマーク ID を含む要求を受け取ると、最初に、要求が有効かどうかをチェックします。 有効でない場合は、エラー応答が生成されます。 この関数では、要求が有効な場合、そのブックマーク ID が Azure Cosmos DB データベースに存在するかどうかをチェックします。 存在しない場合は、エラー応答が生成されます。 ブックマーク ID が見つかると、正常な応答が生成されます。
データはどこかに保存する必要があります。 前のフローチャートでは、データ ストアは Azure Cosmos DB インスタンスです。 しかし、関数からデータベースに接続し、データを読み取るにはどうすればよいのでしょうか。 関数の世界では、そのジョブのために "入力バインディング" を構成します。 Azure portal から入力バインディングを構成するのは簡単です。 この後すぐわかるように、コードを記述したり、ストレージ接続を開いたりする必要はありません。 Azure Functions ランタイムとバインディングによって、これらのタスクが自動的に処理されます。
Azure Cosmos DB アカウントを作成する
Note
この演習は Azure Cosmos DB のチュートリアルではありません。 詳細については、このモジュールの最後にある Azure Cosmos DB に関する完全なラーニング パスを参照してください。
データベース アカウントを作成する
データベース アカウントとは、1 つ以上のデータベースを管理するためのコンテナーです。 データベースを作成するには、データベース アカウントを作成しておく必要があります。
Azure portal のリソース メニューまたはホーム ページで、[リソースの作成] を選択します。 [リソースの作成] ウィンドウが表示されます。
[リソースの作成] メニューで、[データベース] を選択し、Azure Cosmos DB を検索して選択します。 [ワークロードに最適な API はどれですか?] ペインが表示されます。
[Azure Cosmos DB for NoSQL] オプションで、[作成] を選択して、Cosmos DB トリガーと入出力バインディングを作成できるようにします。 [Azure Cosmos DB アカウントの作成 - Azure Cosmos DB for NoSQL] ペインが表示されます。
[基本] タブで、各設定に対して次の値を入力します。
設定 値 説明 プロジェクトの詳細 サブスクリプション コンシェルジェ サブスクリプション サンドボックス内のリソースと連携する Azure サブスクリプション。 リソース グループ ドロップダウン リストから、 [サンドボックス リソース グループ名] を選択しますサンドボックスのリソース グループ。 インスタンスの詳細 アカウント名 globally unique name
Azure Cosmos DB アカウントに一意で識別可能な名前を入力します。指定した名前に documents.azure.com
が追加されます。3 - 50 lowercase characters, numbers, or hyphens (-)
。場所 region
最寄りのリージョンを選択します。 残りの設定は既定値をそのまま使用し、[確認と作成] を選択して入力内容を検証します。 "検証が完了しました" という通知が表示されます。
[作成] を選択し、データベース アカウントをプロビジョニングし、デプロイします。
デプロイには時間がかかることがあります。 通知ハブに "デプロイに成功しました" というメッセージが表示されるまで待ってから次に進みます。
ポータルで [リソースに移動] を選択して、データベース アカウントに移動します。 Azure Cosmos DB アカウントの [クイック スタート] ペインが表示されます。
次に、コンテナーを追加した後、Azure Cosmos DB アカウントにデータベースを追加します。
コンテナーの追加
Azure Cosmos DB では、"コンテナー" を使用して、ユーザーが生成したさまざまなエンティティ ("項目" とも呼ばれます) を保存します。 Bookmarks という名前のコンテナーを作成します。
データ エクスプローラー ツールを使用して、データベースとコンテナーを作成しましょう。
[Azure Cosmos DB アカウント] メニューで、[データ エクスプローラー] を選択します。 ご自分の Cosmos DB アカウントの [データ エクスプローラー] ペインが表示されます。
[新しいコンテナー] ボックスを選択します。 [新しいコンテナー] ペインが表示されます。 これを表示するにはスクロールが必要になる場合があります。
各設定に対して次の値を入力します。
設定 値 説明 データベース ID [新規作成] を選択し、データベース ID に「func-io-learn-db」と入力します データベース名は、1 ~ 255 文字の長さにすることができ、 /, \\, #, ?
、末尾のスペースは使用できません。
自由に入力できますが、このモジュールでは、「func-io-learn-db」を使用します。データベースの最大 RU/秒 4000 既定のスループットである 4000 要求ユニット/秒 (RU/秒) のままにします。 待ち時間を短縮するために、後でパフォーマンスをスケールアップできます。 コンテナー ID Bookmarks コンテナー ID には、データベース名と同じ文字要件があります。 このモジュールでは、"ブックマーク" を使用しています。 パーティション キー /id パーティション キーで、Azure Cosmos DB コレクション内のドキュメントを論理データ パーティション間でどのように分散するかを指定します。 このモジュールでは、データベースのパフォーマンスを考慮していないため、便宜上 "パーティション キー" 設定を使用します。 Azure Cosmos DB パーティション キー戦略の詳細については、Microsoft Learn Azure Cosmos DB モジュールを参照してください。 他のすべての設定については、既定値をそのまま使用します。
ページの下部までスクロールし、[OK] を選択します。 データベースとコンテナーがビルドされるまで数分かかります。
完了すると、データ エクスプローラーでは、[NOSQL API] の下の [データ] に [func-io-learn-db] が表示されます。
func-io-learn-db を選択して展開します。 func-io-learn-db データベースに、スケールやブックマークなど、子メンバーがいくつか含まれていることに注目します。
Bookmarks コンテナーを展開します。 複数の子メンバーが既に事前設定されていることに注目してください。
次のタスクでは、データ (アイテムとも呼ばれます) を Bookmarks コンテナーに追加します。
テスト データを追加する
Bookmarks コンテナーにデータを追加したいとします。 データ エクスプローラーを使用して、各アイテムの URL と ID を保存します。
func-io-learn-db データベース、Bookmarks コンテナーの順に展開して、[項目] を選択します。 [項目] タブが表示されます。
コマンド バーの [新しい項目] を選択します。
新しい項目の既定のコードを次の JSON コードに置き換えます。
{ "id": "docs", "url": "https://learn.microsoft.com/azure" }
コマンド バーの [保存] を選択します。
追加した 2 行よりも多くのプロパティが表示されることに注目します。 これらはすべて、下線
(_rid, _self, _etag, _attachments, _ts)
で始まっています。 これらのプロパティは、次の表に示すように、コンテナーに追加するアイテムの管理を支援するためにシステムによって生成されます。プロパティ 説明 _rid
リソース ID は一意の識別子であり、リソース モデルのリソース スタックごとの階層も示します。 この ID は項目リソースの配置と移動のために内部で使用されます。 _self
リソースのアドレス可能な一意の URI。 _etag
オプティミスティック同時実行制御に必要です。 _attachments
添付リソースのアドレス可能パス。 _ts
このリソースの最終更新を示すタイムスタンプ。 Bookmarks コンテナーに、さらに項目をいくつか追加しましょう。 コマンド バーの [新しい項目] を選択します。 次の内容でさらに 4 つの項目を作成します。 [新しいアイテム] を選択した後、それぞれの新しいアイテムをコピーして貼り付けてから [保存] を選択することで、アイテムを追加します。 各項目が項目の一覧にどのように追加されているかに注目してください。
{ "id": "portal", "url": "https://portal.azure.com" }
{ "id": "learn", "url": "https://learn.microsoft.com/training" }
{ "id": "marketplace", "url": "https://azuremarketplace.microsoft.com/marketplace/apps" }
{ "id": "blog", "url": "https://azure.microsoft.com/blog" }
ブックマーク データの入力が完了すると、コンテナーは次の図のようになります。
Bookmarks コンテナーに項目が 5 つあります。 このシナリオでは、"id=docs" を含む要求が届くと、Bookmarks コンテナー内でその ID が検索され、URL https://learn.microsoft.com/azure
が返されます。 自分の Bookmarks コンテナー内の値を検索する Azure 関数を作成しましょう。
関数を作成する
前のユニットで作成した関数アプリに移動します。 リソース メニューで [ホーム] を選択すると、[最近のリソース] セクションに、ご自分の関数アプリが表示されているはずです ([種類] が 関数アプリ に等しい)。 関数アプリを開きます。 [関数アプリ] ペインが表示されます。
[概要] ページの [関数] タブには、[HttpTrigger1] という関数が 1 つ表示されているはずです。
関数をもう 1 つ作成しましょう。 [関数] タブで [作成] を選択します。[関数の作成] ペインが開き、サポートされているトリガーのテンプレートの一覧が表示されます。
[テンプレートの選択] セクションで [HTTP トリガー] を選択し、[次へ] を選択します。
既定の設定はすべてそのまま使用し、[作成] を選択して関数を作成します。
HttpTrigger2 関数の [概要] ペインが表示されます。
関数を検証する
新しい関数をテストして、これまでの進捗を検証できます。
コマンド バーで、[関数の URL の取得] を選択します。 [関数の URL の取得] ダイアログ ボックスが表示されます。
ドロップダウン リストから [既定値 (関数キー)] を選択し、[クリップボードにコピー] アイコンを選択して、[OK] を選択します。
コピーした関数の URL を新しいブラウザー タブのアドレス バーに貼り付けます。URL の末尾にクエリ文字列値
&name=<your name>
を追加し、<your name>
をご自分の名前に置き換えて、Enter キーを押します。 この Azure 関数から、ブラウザーで、パーソナライズされた応答が返るはずです。
これで、関数が必要最小限の動作を行うようになりました。次に、Azure Cosmos DB (このシナリオでは Bookmarks コンテナー) からデータを読み取ってみましょう。
Azure Cosmos DB 入力バインディングを追加する
データベースからデータを読み取るには、入力バインディングを定義する必要があります。 以下でわかるように、データベースと通信できるバインディングはわずかな手順で構成できます。
Azure portal で、上部にある HttpTrigger2 関数メニューの [統合] を選択します。 関数の [統合] ペインが表示されます。
HTTP 出力バインディングで HTTP トリガー要求を作成するテンプレートを使用しました。 Azure Cosmos DB 入力バインディングを追加しましょう。
[トリガーと入力] ボックスで、[入力の追加] を選択します。 [入力の作成] ペインが表示されます。
[バインドの種類] ドロップダウン リストで、[Azure Cosmos DB] を選択します。
[Azure Cosmos DB の詳細] セクションの [Cosmos DB アカウント接続] 設定で、[新規] リンクを選択します。 [新しい Cosmos DB 接続] ダイアログ ボックスが表示されます。
Microsoft.Azure.WebJobs.Extensions.CosmosDB 拡張機能をインストールするように求めるメッセージが表示されたら、[インストール] を選択し、インストールが完了するまで待ちます。
既定では、先ほど作成した Azure Cosmos DB アカウントが Azure によって認識されます。 [OK] を選択して、データベースへの接続を設定します。 データベース アカウントへの "新しい" 接続が構成され、[Cosmos DB アカウント接続] フィールドに表示されます。
特定の ID でブックマークを検索したいので、クエリ文字列で受け取る ID をバインドに関連付けましょう。
[入力の作成] ペイン内の設定を完成させましょう。 各設定に対して次の値を入力します。 各設定の目的の詳細を確認するには、そのフィールドの右側にある情報アイコンを選択します。
設定 値 説明 ドキュメント パラメーター名 bookmark
コードでこのバインディングを識別するための名前。 データベース名 func-io-learn-db
使用するデータベース。 この値は、先ほど設定したデータベース名です。 コレクション名 Bookmarks
データの読み取り元となるコレクション。 この設定が定義されました。 ドキュメント ID id
Bookmarks Azure Cosmos DB コンテナーを作成したときに定義したドキュメント ID を追加します。 パーティション キー /id
Bookmarks Azure Cosmos DB コレクションを作成したときに定義したパーティション キーを追加します。 ここに入力するキー (入力バインディング形式 <key>
で指定します) は、コレクション内のキーと一致する必要があります。SQL クエリ (任意) 空白のまま ID に基づき、一度に 1 ドキュメントだけ取得しています。 そのため、この場合は SQL クエリを使用するより、[ドキュメント ID] 設定でフィルター処理する方が効果的です。 エントリを 1 つ返す SQL クエリを作成することもできます ( SELECT * from b where b.ID = id
)。 このクエリでは確かにドキュメントが返されますが、ドキュメント コレクションのドキュメントを返します。 コードで無駄にコレクションを操作しなければならないことがあります。 複数のドキュメントを取得するときに SQL クエリの手法を使用してください。これらの設定を使用する理由を明確にするため、特定の ID でブックマークを検索したいので、関数がクエリ文字列で受け取る ドキュメント ID を入力バインディングに関連付けました。 この構文は "バインド式" と呼ばれます。 関数は、クエリ文字列を使用して検索する ID を指定した HTTP 要求によってトリガーされます。 ID はコレクション内で一意となるため、バインディングにより 0 個 (見つからない場合) または 1 個 (見つかった場合) のドキュメントが返されます。
この入力バインディング構成を保存するには、[追加] を選択します。
関数の実装を更新する
バインディングの定義が完了したので、関数でこれを使用できます。 作成したバインディングを実装するには、以下の 2 つの変更を行う必要があります。
関数の言語固有の実装コードを変更します。 これは、関数に渡された ID と一致するドキュメントがデータベースで見つかったかどうかを判断する必要があります。
関数の JSON 実装コードを変更して、クエリ文字列内で渡されるパラメーターが受け入れられるようにします。
関数の JavaScript 実装コードを変更する
HttpTrigger2 関数の [関数] メニューで、[コードとテスト] を選択します。 HttpTrigger2 関数の [コード + テスト] ペインが表示されます。
index.js ファイル内のすべてのコードを次のコードに置き換えます。
module.exports = function (context, req) { var bookmark = context.bindings.bookmark if(bookmark){ context.res = { body: { "url": bookmark.url }, headers: { 'Content-Type': 'application/json' } }; } else { context.res = { status: 404, body : "No bookmarks found", headers: { 'Content-Type': 'application/json' } }; } context.done(); };
コマンド バーの [保存] を選択します。 ログ ペインの上部中央にあるドロップダウンで [ファイルシステム ログ] を選択します (既定では App Insights ログが表示されます)。 [ログ] ペインが表示され、接続されていることを示す
Connected!
が表示されます。
このコードで実行されていることを確認してみましょう。
受信 HTTP 要求によって関数がトリガーされ、
id
クエリ パラメーターが Azure Cosmos DB 入力バインディングに渡されます。データベースがこの ID に一致するドキュメントを発見した場合、
bookmark
パラメーターは見つかったドキュメントに設定されます。この例では、コードによって、データベースの対応するドキュメントで見つかった URL 値を含む応答が作成されます。
このキーに一致するドキュメントが見つからない場合、要求は、ペイロードと、ドキュメントが見つからなかったことをユーザーに伝える状態コードで応答します。
関数の JSON 実装コードを変更する
<functionapp> \ HttpTrigger2 \
パスのドロップダウン リストから function.json を選択します。function.json ファイル内のすべてのコードを次のコードに置き換えます。 必ず、
your-database
をご利用の Azure Cosmos DB アカウントの名前に置き換えてください。{ "bindings": [ { "authLevel": "function", "type": "httpTrigger", "direction": "in", "name": "req", "methods": [ "get", "post" ] }, { "type": "http", "direction": "out", "name": "res" }, { "name": "bookmark", "direction": "in", "type": "cosmosDB", "partitionKey": "{id}", "databaseName": "func-io-learn-db", "containerName": "Bookmarks", "connection": "your-database_DOCUMENTDB", "id": "{id}", } ] }
コマンド バーの [保存] を選択します。
関数の PowerShell 実装コードを変更する
HttpTrigger2 関数の [関数] メニューで、[コードとテスト] を選択します。 HttpTrigger2 関数の [コードとテスト] ペインが表示され、
run.ps1
ファイルが表示されます。run.ps1
ファイル内のすべてのコードを次のコードに置き換えます。using namespace System.Net param($Request, $bookmark, $TriggerMetadata) if ($bookmark) { $status = [HttpStatusCode]::OK $body = @{ url = $bookmark.url } } else { $status = [HttpStatusCode]::NotFound $body = "No bookmarks found" } Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = $status Body = $body })
コマンド バーの [保存] を選択します。 ログ ペインの上部中央にあるドロップダウンで [ファイルシステム ログ] を選択します (既定では App Insights ログが表示されます)。 [ログ] ペインが表示され、接続されていることを示す
Connected!
が表示されます。
このコードで実行されていることを確認してみましょう。
受信 HTTP 要求によって関数がトリガーされ、
id
クエリ パラメーターが Azure Cosmos DB 入力バインディングに渡されます。データベースがこの ID に一致するドキュメントを発見した場合、
bookmark
パラメーターは見つかったドキュメントに設定されます。この例では、コードによって、データベースの対応するドキュメントで見つかった URL 値を含む応答が作成されます。
このキーに一致するドキュメントが見つからない場合、要求は、ペイロードと、ドキュメントが見つからなかったことをユーザーに伝える状態コードで応答します。
関数の JSON 実装コードを変更する
<functionapp> \ HttpTrigger2 \
パスのドロップダウン リストから function.json を選択します。id
とpartitionKey
の値を変更して、{id}
のパラメーターを受け入れるようにします。 function.json コードは次の例のようになります。your-database
は、ご自分の Cosmos DB データベースの名前に置き換えます。{ "bindings": [ { "authLevel": "function", "type": "httpTrigger", "direction": "in", "name": "Request", "methods": [ "get", "post" ] }, { "type": "http", "direction": "out", "name": "Response" }, { "type": "cosmosDB", "name": "bookmark", "databaseName": "func-io-learn-db", "containerName": "Bookmarks", "connection": "your-database_DOCUMENTDB", "direction": "in", "id": "{id}", "partitionKey": "{id}" } ] }
コマンド バーの [保存] を選択します。
試してみる
HttpTrigger2 関数の [コードとテスト] ペインが既に表示されているはずです。
コマンド バーで、[関数の URL の取得] を選択します。 [関数の URL の取得] ダイアログ ボックスが表示されます。
[キー] ドロップダウン リストから [関数キー] の下の [既定値] を選択し、URL の末尾にある [クリップボードにコピー] アイコンを選択します。
コピーした関数キーを新しいブラウザー タブのアドレス バーに貼り付け、URL の末尾にクエリ文字列値
&id=docs
を追加します。 結果の URL は次の例のようになります。https://example.azurewebsites.net/api/HttpTrigger2?code=AbCdEfGhIjKlMnOpQrStUvWxYz==&id=docs
Enter キーを押して、要求を実行します。 関数から返される応答は、次の例のようになります。
{ "url": "https://learn.microsoft.com/azure" }
&id=docs
を&id=missing
に置き換え、Enter キーを押して応答を確認します。 5 つのブックマークを定義し、要求されたブックマークが存在しない場合に意味のあるエラー応答を作成しました。
このユニットでは、Azure Cosmos DB データベースから読み取るために、最初の入力バインディングを手動で作成しました。 バインディングにより、データベースを検索してデータを読み取るために記述するコードの量が最小限に抑えられました。 作業のほとんどは、宣言によってバインドを構成することで行い、残りはプラットフォームによって処理されました。
次のユニットでは、Azure Cosmos DB 出力バインディングを通してブックマーク コレクションにさらにデータを追加します。