Azure Functionsを使用すると、独自の統合コードを記述することなく、Azure サービスやその他のリソースを関数に接続できます。 これらのバインドは、入力と出力の両方を表し、関数定義内で宣言されます。 バインドからのデータは、パラメーターとして関数に提供されます。 "トリガー" は、特殊な種類の入力バインドです。 関数はトリガーを 1 つしか持てませんが、複数の入力および出力バインドを持つことができます。 詳細については、「Azure Functions トリガーとバインドの概念を参照してください。
この記事では、Visual Studio Code を使用して、前のクイック スタート記事で作成した関数にAzure Storageを接続する方法について説明します。 この関数に追加する出力バインドは、HTTP 要求から Azure Queue storage キュー内のメッセージにデータを書き込みます。
ほとんどのバインディングには、バインドされたサービスにアクセスするために Functions が使用する格納された接続文字列が必要です。 簡単にするために、関数アプリで作成したstorage アカウントを使用します。 このアカウントへの接続は、既に AzureWebJobsStorage という名前のアプリ設定に保存されています。
注
この記事では現在 Node.js v4 for Functions をサポートしています。
ローカル環境を構成する
操作を始める前に、以下の要件を満たしておく必要があります。
Visual Studio Code の
Azure Storage 拡張機能をインストールします。 Azure Storage Explorerをインストールします。 Storage Explorerは、出力バインディングによって生成されたキュー メッセージを調べるのに使用するツールです。 Storage Explorerは、macOS、Windows、Linux ベースのオペレーティング システムでサポートされています。
- .NET Core CLI ツールをインストールします。
- Azureでの関数の作成 (Visual Studio Code を使用) に関するパート 1 の手順を完了する。
この記事では、Visual Studio Code から Azure サブスクリプションに既にサインインしていることを前提としています。 サインインするには、コマンド パレットから Azure: Sign In を実行します。
関数アプリの設定をダウンロードする
前のクイック スタート記事では、必要なstorage アカウントと共にAzureで関数アプリを作成しました。 このアカウントのconnection stringは、Azureのアプリ設定に安全に保存されます。 この記事では、同じアカウントのStorage キューにメッセージを書き込みます。 関数をローカルで実行するときにstorage アカウントに接続するには、アプリ設定を local.settings.json ファイルにダウンロードする必要があります。
F1 を押してコマンド パレットを開き、コマンド
Azure Functions: Download Remote Settings...を検索して実行します。前の記事で作成した関数アプリを選択します。 [すべてはい] を選択して既存のローカル設定を上書きします。
重要
local.settings.json ファイルは、機密情報が含まれているため、公開されることはなく、ソース管理から除外されます。
storage アカウントの接続文字列のキーである値
AzureWebJobsStorageをコピーします。 この接続を使用して、出力バインドが期待どおりに動作することを確認します。
バインディング拡張機能を登録する
キューストレージ出力バインドを使用しているため、プロジェクトを実行する前に、ストレージバインド拡張機能をインストールしておく必要があります。
projectは、extension バンドル を使用するように構成されています。これによって、定義済みの一連の拡張機能パッケージが自動的にインストールされます。
拡張機能バンドルは、projectのルートにある host.json ファイルで既に有効になっています。これは次の例のようになります。
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.*, 4.0.0)"
}
}
これで、ストレージ出力バインディングをプロジェクトに追加できるようになりました。
projectは、extension バンドル を使用するように構成されています。これによって、定義済みの一連の拡張機能パッケージが自動的にインストールされます。
拡張機能バンドルは、projectのルートにある host.json ファイルで既に有効になっています。これは次の例のようになります。
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
これで、ストレージ出力バインディングをプロジェクトに追加できるようになりました。
HTTP トリガーとタイマー トリガーを除き、バインドは拡張機能パッケージとして実装されます。 ターミナル ウィンドウで次の dotnet add package コマンドを実行して、Storage拡張機能パッケージをprojectに追加します。
dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues --prerelease
これで、ストレージ出力バインディングをプロジェクトに追加できるようになりました。
出力バインディングを追加する
Azure Storage キューに書き込むには:
バインド構成に
extraOutputsプロパティを追加する{ methods: ['GET', 'POST'], extraOutputs: [sendToQueue], // add output binding to HTTP trigger authLevel: 'function', handler: () => {} }output.storageQueue呼び出しの上にapp.http関数を追加するconst sendToQueue = output.storageQueue({ queueName: 'outqueue', connection: 'AzureWebJobsStorage', });
Azure Storage キューに書き込むには:
バインド構成に
extraOutputsプロパティを追加する{ methods: ['GET', 'POST'], extraOutputs: [sendToQueue], // add output binding to HTTP trigger authLevel: 'function', handler: () => {} }output.storageQueue呼び出しの上にapp.http関数を追加するconst sendToQueue: StorageQueueOutput = output.storageQueue({ queueName: 'outqueue', connection: 'AzureWebJobsStorage', });
Functions では、各種のバインドで direction、type、固有の name が必要です。 これらの属性を定義する方法は、関数アプリの言語によって異なります。
バインド属性は、特定の関数の function.json ファイルで定義されます。 バインドの種類によっては、追加のプロパティが必要になることもあります。 キュー出力構成では、Azure Storage キュー バインドに必要なフィールドについて説明します。 この拡張機能により、バインドを簡単に function.json ファイルに追加できます。
バインドを作成するには、HttpTrigger フォルダー内の function.json ファイルを右クリック (macOS では Ctrl キーを押しながらクリック) して、 [バインドの追加] を選択します。プロンプトに従って、新しいバインドの次のバインド プロパティを定義します。
| Prompt | 値 | 説明 |
|---|---|---|
| バインド方向を選択する | out |
バインドは出力バインドです。 |
| 方向を使用してバインドを選択する... | Azure Queue Storage |
バインドは、Azure Storage キュー バインドです。 |
| コードでこのバインドの特定に使用する名前 | msg |
コードで参照されているバインド パラメーターを識別する名前。 |
| メッセージの送信先のキュー | outqueue |
バインドが書き込むキューの名前。 queueName が存在しない場合は、バインドによって最初に使用されるときに作成されます。 |
| "local.setting.json" から設定を選択する | AzureWebJobsStorage |
Storage アカウントの接続文字列を含むアプリケーション設定の名前。
AzureWebJobsStorage設定には、関数アプリで作成したストレージアカウントの接続文字列が含まれています。 |
バインドは、bindings の 配列に追加されます。これは次のようになります。
"name": "msg",
"queueName": "outqueue",
"connection": "AzureWebJobsStorage"
}
]
}
バインド属性は、function_app.py ファイル内の特定の関数コードを修飾することによって定義されます。
queue_output デコレーターを使用して、Azure Queue ストレージの出力バインディングを追加します。
queue_output デコレーターを使用すると、バインディングの方向は暗黙的に 'out' になり、型は Azure Storage Queue です。
function_app.pyの関数コードに次のデコレーターを追加します。
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
このコードでは、arg_name はコードで参照されるバインド パラメーターを識別します。queue_name はバインドが書き込むキューの名前、connection は、Storage アカウントのconnection stringを含むアプリケーション設定の名前です。 クイック スタートでは、AzureWebJobsStorage 設定にある関数アプリと同じstorage アカウントを使用します。
queue_name が存在しない場合は、バインドによって最初に使用されるときに作成されます。
C# projectでは、バインドは関数メソッドのバインド属性として定義されます。 具体的な定義は、お使いのアプリがインプロセス (C# クラス ライブラリ) で実行されるのか、分離ワーカー プロセスで実行されるのかによって異なります。
HttpExample.cs project ファイルを開き、次の MultiResponse クラスを追加します。
public class MultiResponse
{
[QueueOutput("outqueue", Connection = "AzureWebJobsStorage")]
public string[] Messages { get; set; }
public IActionResult HttpResponse { get; set; }
}
MultiResponse クラスを使用すると、outqueue という名前のstorage キューと HTTP 成功メッセージに書き込むことができます。
QueueOutput 属性は文字列配列に適用されるので、複数のメッセージをキューに送信できます。
Connection プロパティは、storage アカウントのconnection stringを設定します。 この場合、既定のstorage アカウントを既に使用しているため、Connection を省略できます。
Java projectでは、バインドは関数メソッドのバインド注釈として定義されます。 その後、これらの注釈に基づいて function.json ファイルが自動的に生成されます。
src/main/java で関数コードの場所を参照し、Function.java project ファイルを開き、run メソッド定義に次のパラメーターを追加します。
@QueueOutput(name = "msg", queueName = "outqueue",
connection = "AzureWebJobsStorage") OutputBinding<String> msg,
msg パラメーターは、OutputBinding<T> 型です。これは、関数の完了時に出力バインドにメッセージとして書き込まれる文字列のコレクションを表します。 この場合、出力は outqueue という名前のstorage キューです。 Storage アカウントのconnection stringは、connection メソッドによって設定されます。 connection string自体ではなく、Storage アカウントを含むアプリケーション設定をconnection string渡します。
run メソッドの定義は次の例のようになります。
@FunctionName("HttpExample")
public HttpResponseMessage run(
@HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS)
HttpRequestMessage<Optional<String>> request,
@QueueOutput(name = "msg", queueName = "outqueue",
connection = "AzureWebJobsStorage") OutputBinding<String> msg,
final ExecutionContext context) {
出力バインディングを使用するコードを追加する
バインドが定義されたら、バインドのnameを使用して、関数シグネチャの属性としてアクセスできます。 出力バインドを使用することで、認証、キュー参照の取得、データの書き込みに Azure Storage SDK コードを使用する必要はありません。 Functions ランタイムおよびキューの出力バインドが、ユーザーに代わってこれらのタスクを処理します。
context.extraOutputs の出力バインド オブジェクトを使用してキュー メッセージを作成するコードを追加します。 このコードを return ステートメントの前に追加します。
context.extraOutputs.set(sendToQueue, [msg]);
この時点で、関数は次のようになります。
const { app, output } = require('@azure/functions');
const sendToQueue = output.storageQueue({
queueName: 'outqueue',
connection: 'AzureWebJobsStorage',
});
app.http('HttpExample', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
extraOutputs: [sendToQueue],
handler: async (request, context) => {
try {
context.log(`Http function processed request for url "${request.url}"`);
const name = request.query.get('name') || (await request.text());
context.log(`Name: ${name}`);
if (name) {
const msg = `Name passed to the function ${name}`;
context.extraOutputs.set(sendToQueue, [msg]);
return { body: msg };
} else {
context.log('Missing required data');
return { status: 404, body: 'Missing required data' };
}
} catch (error) {
context.log(`Error: ${error}`);
return { status: 500, body: 'Internal Server Error' };
}
},
});
context.extraOutputs の出力バインド オブジェクトを使用してキュー メッセージを作成するコードを追加します。 このコードを return ステートメントの前に追加します。
context.extraOutputs.set(sendToQueue, [msg]);
この時点で、関数は次のようになります。
import {
app,
output,
HttpRequest,
HttpResponseInit,
InvocationContext,
StorageQueueOutput,
} from '@azure/functions';
const sendToQueue: StorageQueueOutput = output.storageQueue({
queueName: 'outqueue',
connection: 'AzureWebJobsStorage',
});
export async function HttpExample(
request: HttpRequest,
context: InvocationContext,
): Promise<HttpResponseInit> {
try {
context.log(`Http function processed request for url "${request.url}"`);
const name = request.query.get('name') || (await request.text());
context.log(`Name: ${name}`);
if (name) {
const msg = `Name passed to the function ${name}`;
context.extraOutputs.set(sendToQueue, [msg]);
return { body: msg };
} else {
context.log('Missing required data');
return { status: 404, body: 'Missing required data' };
}
} catch (error) {
context.log(`Error: ${error}`);
return { status: 500, body: 'Internal Server Error' };
}
}
app.http('HttpExample', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
handler: HttpExample,
});
Push-OutputBinding コマンドレットと msg 出力バインディングを使用してキューにテキストを書き込むコードを追加します。
if ステートメントで OK ステータスを設定する前に、このコードを追加してください。
$outputMsg = $name
Push-OutputBinding -name msg -Value $outputMsg
この時点で、関数は次のようになるはずです。
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
$name = $Request.Body.Name
}
if ($name) {
# Write the $name value to the queue,
# which is the name passed to the function.
$outputMsg = $name
Push-OutputBinding -name msg -Value $outputMsg
$status = [HttpStatusCode]::OK
$body = "Hello $name"
}
else {
$status = [HttpStatusCode]::BadRequest
$body = "Please pass a name on the query string or in the request body."
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = $status
Body = $body
})
次のコードに合わせて HttpExample\function_app.py を更新し、関数の定義に msg パラメーターを、msg.set(name) ステートメントの下に if name: を追加してください。
import azure.functions as func
import logging
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
@app.route(route="HttpExample")
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
def HttpExample(req: func.HttpRequest, msg: func.Out [func.QueueMessage]) -> 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:
msg.set(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
)
msg パラメーターは、azure.functions.Out classのインスタンスです。
set メソッドはキューに文字列メッセージを書き込みます。 この場合は、URL クエリ文字列の中で関数に渡される name です。
既存の Run メソッドを次のコードに置き換えます。
[Function("HttpExample")]
public MultiResponse Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
var message = "Welcome to Azure Functions!";
// Return a response to both HTTP trigger and storage output binding.
return new MultiResponse()
{
// Write a single message.
Messages = new string[] { message },
HttpResponse = new OkObjectResult(message)
};
}
これで、新しい msg パラメーターを使用して、関数コードから出力バインドに書き込むことができます。 成功応答の前に次のコード行を追加して、name の値を msg 出力バインドに追加します。
msg.setValue(name);
出力バインドを使用する場合、認証、キュー参照の取得、データの書き込みに Azure Storage SDK コードを使用する必要はありません。 Functions ランタイムおよびキューの出力バインドが、ユーザーに代わってこれらのタスクを処理します。
run メソッドは次の例のようになります。
@FunctionName("HttpExample")
public HttpResponseMessage run(
@HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS)
HttpRequestMessage<Optional<String>> request,
@QueueOutput(name = "msg", queueName = "outqueue",
connection = "AzureWebJobsStorage") OutputBinding<String> msg,
final ExecutionContext context) {
context.getLogger().info("Java HTTP trigger processed a request.");
// Parse query parameter
String query = request.getQueryParameters().get("name");
String name = request.getBody().orElse(query);
if (name == null) {
return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
.body("Please pass a name on the query string or in the request body").build();
} else {
// Write the name to the message queue.
msg.setValue(name);
return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
}
}
テストを更新する
アーキタイプはテストのセットも作成するため、msg メソッド シグネチャ内の新しい run パラメーターを処理するためにこれらのテストを更新する必要があります。
src/test/java でテスト コードの場所を参照し、Function.java project ファイルを開き、//Invoke のコード行を次のコードに置き換えます。
@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
final HttpResponseMessage ret = new Function().run(req, msg, context);
関数をローカルで実行する
Visual Studio Code は Azure Functions Core ツール と統合され、Azureに発行する前にローカル開発コンピューターでこのprojectを実行できます。 Core Tools をローカルにまだインストールしていない場合は、projectを初めて実行するときにインストールするように求められます。
関数を呼び出すには、F5 を押して関数アプリのprojectを開始します。 ターミナル パネルに、Core Tools からの出力が表示されます。 アプリがターミナル パネルで起動します。 HTTP によってトリガーされる関数の URL エンドポイントがローカルで実行されていることを確認できます。
Core Tools がまだインストールされていない場合は、Install を選択し、指示が表示されたら Core Tools をインストールします。
Windows で実行できない場合は、Visual Studio Code の既定のターミナルが WSL Bash に設定されていないことを確認してください。Core Tools が実行されたら、Azure: Functions 領域に移動します。 Functions で、Local Project>Functions を展開します。 関数を右クリック (Windows) または
HttpExampleキーを押しながらクリック (macOS) して、[Execute Function Now]\(今すぐ関数を実行\) を選択します。
[Enter request body] (要求本文を入力してください) で、Enter キーを押して要求メッセージを関数に送信します。
関数がローカルで実行され、応答を返すと、Visual Studio Code で通知が発生します。 関数の実行に関する情報は、ターミナル パネルに表示されます。
Ctrl + C キーを押して Core Tools を停止し、デバッガーの接続を解除します。
関数をローカルで実行する
前の記事と同様に、F5 を押して、関数アプリのprojectと Core Tools を起動します。
Core Tools が実行されたら、Azure: Functions 領域に移動します。 Functions で、Local Project>Functions を展開します。
HttpExample関数を右クリック (Mac では Ctrl キーを押しながらクリック) し、[Execute Function Now...] (今すぐ関数を実行...) を選択します。
Enter 要求本文には、
{ "name": "Azure" }の要求メッセージ本文の値が表示されます。 Enter キーを押して、この要求メッセージを関数に送信します。応答が返されたら、Ctrl + C キーを押して Core Tools を停止します。
storage connection stringを使用しているため、関数はローカルで実行するときにAzure storage アカウントに接続します。 出力バインドが最初に使用されるときに、Functions ランタイムによってストレージアカウントに新しいキュー outqueue が作成されます。 Storage Explorerを使用して、キューが新しいメッセージと共に作成されたことを確認します。
Storage Explorerをアカウントに接続する
Azure Storage Explorerを既にインストールし、Azure アカウントに接続している場合は、このセクションをスキップします。
Azure Storage Explorer ツールを実行し、左側の接続アイコンを選択し、 アカウントの追加を選択します。
[Connect ダイアログで、 Azure アカウントの追加を選択し、Azure環境を選択し、Sign in... を選択します。。
アカウントに正常にサインインすると、アカウントに関連付けられているすべてのAzureサブスクリプションが表示されます。 サブスクリプションを選択し、[エクスプローラーを開く] を選択します。
出力キューを確認する
Visual Studio Code で、F1 キーを押してコマンド パレットを開き、コマンド
Azure Storage: Open in Storage Explorerを検索して実行し、storage アカウント名を選択します。 Azure Storage Explorerでstorage アカウントが開きます。[キュー] ノードを展開して、outqueue という名前のキューを選択します。
このキューには、HTTP によってトリガーされる関数を実行したときにキューの出力バインディングが作成されたというメッセージが含まれます。 既定の
name値が Azure の関数を呼び出した場合、キュー メッセージは Name Azure に渡されます。Azure Storage Explorer に表示されているキュー メッセージのスクリーンショット 関数を再度実行し、別の要求を送信すると、キューに新しいメッセージが表示されます。
次に、更新された関数アプリをAzureに再発行します。
更新したアプリを再デプロイして検証する
Visual Studio コードで、F1 キーを押してコマンド パレットを開きます。 コマンド パレットで、
Azure Functions: Deploy to function app...を検索して選択します。最初の記事で作成した関数アプリを選択します。 projectを同じアプリに再デプロイするため、Deploy を選択して、ファイルの上書きに関する警告を無視します。
デプロイが完了したら、Azureで関数をトリガーするために、再度「今すぐ関数を実行」機能を使用できます。 このコマンドは、関数accessキーを自動的に取得し、HTTP トリガー エンドポイントを呼び出すときに使用します。
storage キュー内のメッセージを確認し出力バインドによってキューに新しいメッセージが生成されることを確認します。
リソースをクリーンアップする
Azureでは、resources は、関数アプリ、関数、ストレージ アカウントなどを指します。 これらは "リソース グループ" に分類されており、グループを削除することでグループ内のすべてのものを削除できます。
これらのクイックスタートを完了するためにリソースを作成しました。 これらのリソースについては、account の状態とサービスの価格に応じて課金される場合があります。 リソースの必要がなくなった場合にそれらを削除する方法を、次に示します。
Visual Studio コードで、F1 キーを押してコマンド パレットを開きます。 コマンド パレットで、
Azure: Open in portalを検索して選択します。関数アプリを選択し、Enter キーを押します。 関数アプリ ページがAzure portalで開きます。
[概要] タブで、 [リソース グループ] の横にある名前付きリンクを選択します。
[リソース グループ] ページで、含まれているリソースの一覧を確認し、削除するものであることを確認します。
[リソース グループの削除] を選択し、指示に従います。
削除には数分かかることがあります。 実行されると、通知が数秒間表示されます。 ページの上部にあるベルのアイコンを選択して、通知を表示することもできます。
次のステップ
HTTP トリガーの関数を更新して、データをストレージ キューに書き込むようにしました。 Visual Studio Code を使用した関数の開発の詳細を確認できます。
Azure Functions を Visual Studio Code で開発する
JavaScript の完全な関数プロジェクトのサンプル。
Java の完全な関数プロジェクトのサンプル。
TypeScript の完全な関数プロジェクトのサンプル。
Python の完全な関数プロジェクトのサンプル。
PowerShell の完全な関数プロジェクトのサンプル。