使用 Visual Studio Code 將 Azure Functions 連線至 Azure 儲存體
Azure Functions 可讓您直接將 Azure 服務和其他資源連線至函式,而不需要自行撰寫整合程式碼。 這些繫結同時代表輸入和輸出,會宣告於函式定義內。 繫結中的資料會提供給函式作為參數。 「觸發程序」是一種特殊的輸入繫結。 雖然函式只有一個觸發程序,但可以有多個輸入和輸出繫結。 若要深入了解,請參閱 Azure Functions 觸發程序和繫結概念。
本文會帶您了解如何使用 Visual Studio Code 將 Azure 儲存體連線至您在上一篇快速入門文章中建立的函式。 您新增至此函式的輸出繫結,會將資料從 HTTP 要求寫入至位於 Azure 佇列儲存體佇列中的訊息。
大部分的繫結都需要函式用來存取繫結服務的預存連接字串。 為了方便作業,可使用您以函數應用程式建立的儲存體帳戶。 此帳戶的連線已儲存在名為 AzureWebJobsStorage
的應用程式設定中。
注意
本文目前支援適用於 Functions 的 Node.js v4。
設定您的本機環境
開始之前必須符合下列需求:
安裝適用於 Visual Studio Code 的 Azure 儲存體擴充 \(英文\)。
安裝 Azure 儲存體總管。 需使用儲存體總管這項工具來檢查由輸出繫結所產生的佇列訊息。 儲存體總管支援安裝在以 macOS、Windows 和 Linux 為基礎的作業系統上。
安裝 .NET Core CLI 工具。
完成 Visual Studio Code 快速入門第 1 部分中的步驟。
- 完成 Visual Studio Code 快速入門第 1 部分中的步驟。
- 完成 Visual Studio Code 快速入門第 1 部分中的步驟。
- 完成 Visual Studio Code 快速入門第 1 部分中的步驟。
- 完成 Visual Studio Code 快速入門第 1 部分中的步驟。
- 完成 Visual Studio Code 快速入門第 1 部分中的步驟。
此文章假設您已從 Visual Studio Code 登入您的 Azure 訂用帳戶。 您可以從命令選擇區執行 Azure: Sign In
來登入。
下載函式應用程式設定
在先前的快速入門文章中,您已在 Azure 中建立函數應用程式與必要的儲存體帳戶。 此帳戶的連接字串會安全地儲存在 Azure 的應用程式設定中。 在本文中,您會將訊息寫入至相同帳戶中的儲存體佇列。 在本機執行函式時若要連線至儲存體帳戶,必須將應用程式設定下載到 local.settings.json 檔案。
按 F1 鍵可開啟命令選擇區,然後請搜尋並執行
Azure Functions: Download Remote Settings...
命令。選擇您在先前的文章中所建立的函式應用程式。 選取 [全部皆是] 來覆寫現有的本機設定。
重要
由於 local.settings.json 檔案中包含祕密,因此一律不會受到發佈,且會排除在原始檔控制範圍之外。
複製
AzureWebJobsStorage
值,其為儲存體帳戶連接字串值的金鑰。 您將使用此連線來確認輸出繫結會如預期般運作。
註冊繫結延伸模組
由於您是使用佇列儲存體輸出繫結,您必須先安裝儲存體繫結擴充才能執行專案。
您的專案已設定為使用擴充功能配套,這會自動安裝一組預先定義的擴充功能套件。
擴充功能配套已在專案根目錄的 host. json 檔案中啟用,如下所示:
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.*, 4.0.0)"
}
}
現在,您可以將儲存體輸出繫結新增至您的專案。
您的專案已設定為使用擴充功能配套,這會自動安裝一組預先定義的擴充功能套件。
擴充功能配套已在專案根目錄的 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 命令來將儲存體套件新增至您的專案。
dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues --prerelease
現在,您可以將儲存體輸出繫結新增至您的專案。
新增輸出繫結
若要寫入至 Azure 儲存體佇列:
將
extraOutputs
屬性新增至繫結組態{ methods: ['GET', 'POST'], extraOutputs: [sendToQueue], // add output binding to HTTP trigger authLevel: 'anonymous', handler: () => {} }
在
app.http
呼叫上方新增output.storageQueue
函式const sendToQueue = output.storageQueue({ queueName: 'outqueue', connection: 'AzureWebJobsStorage', });
若要寫入至 Azure 儲存體佇列:
將
extraOutputs
屬性新增至繫結組態{ methods: ['GET', 'POST'], extraOutputs: [sendToQueue], // add output binding to HTTP trigger authLevel: 'anonymous', handler: () => {} }
在
app.http
呼叫上方新增output.storageQueue
函式const sendToQueue: StorageQueueOutput = output.storageQueue({ queueName: 'outqueue', connection: 'AzureWebJobsStorage', });
在 Functions 中,每種繫結型別都需要 direction
、type
和唯一的 name
。 定義這些屬性的方式會取決於您函式應用程式的語言。
繫結屬性定義於 function.json 檔案的特定函式中。 根據繫結類型,可能需要額外的屬性。 佇列輸出組態會說明 Azure 儲存體佇列繫結所需的欄位。 擴充功能可讓您輕鬆地將繫結加入至 function.json 檔案。
若要建立繫結,請以滑鼠右鍵按一下 (在 macOS 上則為 Ctrl+按一下) HttpTrigger 資料夾中的 function.json
檔案,然後選擇 [新增繫結]。遵循提示來針對新繫結定義下列繫結屬性:
提示 | 值 | Description |
---|---|---|
選取繫結方向 | out |
此繫結為輸出繫結。 |
選取具有下列方向的繫結 | Azure Queue Storage |
此繫結是 Azure 儲存體佇列繫結。 |
用以在程式碼中識別此繫結的名稱 | msg |
識別您的程式碼中參考之繫結參數的名稱。 |
要接收訊息的佇列 | outqueue |
作為繫結寫入目標的佇列名稱。 當 queueName 不存在,繫結會在第一次使用時加以建立。 |
"local.setting.json" 選取設定 | AzureWebJobsStorage |
包含儲存體帳戶連接字串之應用程式設定的名稱。 AzureWebJobsStorage 設定會包含您以函式應用程式建立之儲存體帳戶的連接字串。 |
繫結會新增至 function.json 中的 bindings
陣列,此時應該會顯示如下:
"name": "msg",
"queueName": "outqueue",
"connection": "AzureWebJobsStorage"
}
]
}
繫結屬性是藉由在 function_app.py 檔案中裝飾特定函式程式碼來定義。 您可以使用 queue_output
裝飾項目來新增 Azure 佇列儲存體輸出繫結。
藉由使用 queue_output
裝飾項目,繫結方向會是「輸出」,型別為 Azure 儲存體佇列。 在 HttpExample\function_app.py 中,將下列裝飾項目新增至函式程式碼:
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
在此程式碼中,arg_name
會識別程式碼中參考的繫結參數、queue_name
是寫入繫結的佇列名稱,而 connection
是包含儲存體帳戶連接字串的應用程式設定名稱。 在快速入門中,您會使用與函數應用程式 (AzureWebJobsStorage
設定) 相同的儲存體帳戶。 當 queue_name
不存在,繫結會在第一次使用時加以建立。
在 C# 專案中,是將繫結定義為函式方法上的繫結屬性。 確切的定義取決於您的應用程式是否在程序中執行 (C# 類別庫),還是處於隔離的背景工作處理序中。
開啟 HttpExample.cs 專案檔,並新增下列 MultiResponse
類別:
public class MultiResponse
{
[QueueOutput("outqueue",Connection = "AzureWebJobsStorage")]
public string[] Messages { get; set; }
public HttpResponseData HttpResponse { get; set; }
}
MultiResponse
類別可讓您寫入名為 outqueue
的儲存體佇列和 HTTP 成功訊息。 多個訊息可以傳送至佇列,因為 QueueOutput
屬性會套用至字串陣列。
Connection
屬性會設定儲存體帳戶的連接字串。 在此情況下,您可以省略 Connection
,因為您已經正在使用預設的儲存體帳戶。
在 Java 專案中,繫結會被定義為函式方法上的繫結註釋。 系統接著會根據這些註釋自動產生 function.json 檔案。
瀏覽至 src/main/java 底下您的函式程式碼位置,開啟 Function java 專案檔案,然後將下列參數新增至 run
方法定義:
@QueueOutput(name = "msg", queueName = "outqueue",
connection = "AzureWebJobsStorage") OutputBinding<String> msg,
msg
參數是 OutputBinding<T>
類型,其代表會在函式完成時寫入輸出繫結的字串集合。 在此情況下,輸出是名為 outqueue
的儲存體佇列。 儲存體帳戶的連接字串是由 connection
方法設定。 您會傳遞包含儲存體帳戶連接字串的應用程式設定,而不是連接字串本身。
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 儲存體 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
Cmdlet 的程式碼,以使用 msg
輸出繫結將文字寫入至佇列。 在 if
陳述式中設定「確定」狀態之前,請先新增此程式碼。
$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
})
將 msg
參數新增至函式定義和 if name:
陳述式下的 msg.set(name)
,以更新 HttpExample\function_app.py,使其符合下列程式碼:
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
。
將現有的 HttpExample
類別取代為下列程式碼:
[Function("HttpExample")]
public static MultiResponse Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
FunctionContext executionContext)
{
var logger = executionContext.GetLogger("HttpExample");
logger.LogInformation("C# HTTP trigger function processed a request.");
var message = "Welcome to Azure Functions!";
var response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString(message);
// Return a response to both HTTP trigger and storage output binding.
return new MultiResponse()
{
// Write a single message.
Messages = new string[] { message },
HttpResponse = response
};
}
}
現在,您可以使用新的 msg
參數,從您的函式程式碼寫入輸出繫結。 在成功回應之前新增下列一行程式碼,以將 name
的值新增至 msg
輸出繫結。
msg.setValue(name);
當您使用輸出繫結時,無須使用 Azure 儲存體 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();
}
}
更新測試
因為原型也會建立一組測試,所以您需要更新這些測試,以處理 run
方法簽章中的新 msg
參數。
瀏覽至 src/test/java 底下的測試程式碼位置,開啟 Function.java 專案檔案,並以下列程式碼取代 //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。 如果您尚未在本機安裝 Core Tools,系統會在您第一次執行專案時提示您安裝。
若要呼叫您的函式,請按 F5 以啟動函式應用程式專案。 [終端] 面板會顯示核心工具的輸出。 您的應用程式會在 [終端] 面板中啟動。 您可以查看在本機所執行 HTTP 觸發函式的 URL 端點。
如果您尚未安裝 Core Tools,請在系統提示安裝時選取 [安裝] 來安裝 Core Tools。
如果在 Windows 上執行時遇到問題,請確定 Visual Studio Code 的預設終端機未設定為 WSL Bash。執行 Core Tools 時,移至 [Azure: Functions] 區域。 在 [函式] 下方,展開 [本機專案]>[函式]。 以滑鼠右鍵按一下 (Windows) 或 Ctrl - 點擊 (macOS)
HttpExample
函式,並選擇 [立即執行函式...]。在 [輸入要求本文] 中,按下 Enter 向您的函式傳送要求訊息。
當函式在本機執行並傳回回應時,會在 Visual Studio Code 中引發通知。 [終端機] 面板會顯示函數執行的相關資訊於。
按 Ctrl + C 以停止 Core Tools,並中斷偵錯工具的連線。
在本機執行函式
如先前的文章中所示,按一下 F5 可開啟函式應用程式專案和 Core Tools。
執行 Core Tools 時,移至 [Azure: Functions] 區域。 在 [函式] 下方,展開 [本機專案]>[函式]。 以滑鼠右鍵按一下 (於 macOS 則是 Ctrl + 按一下)
HttpExample
函式,並選取 [立即執行函式]。在 [輸入要求本文] 中,您會看到
{ "name": "Azure" }
的要求訊息本文值。 請按 Enter 鍵,將此要求訊息傳送至您的函式。傳回回應後,按一下 Ctrl + C 以停止 Core Tools。
因為您使用的是儲存體連接字串,所以函式會在本機執行時連到 Azure 儲存體帳戶。 您第一次使用輸出繫結時,Functions 執行階段會在儲存體帳戶中建立名為 outqueue 的新佇列。 您將會使用儲存體總管來確認佇列已連同新訊息一起被建立。
將儲存體總管連線到您的帳戶
如果您已經安裝 Azure 儲存體總管並將它連線至您的 Azure 帳戶,請略過此節內容。
執行 Azure 儲存體總管 工具,選取左側的連線圖示,然後選取 [新增帳戶]。
在 [連線] 對話方塊中,選擇 [新增 Azure 帳戶],選擇您的 [Azure 環境],然後選取 [登入]。
在您成功登入帳戶之後,您會看見與您的帳戶相關聯的所有 Azure 訂用帳戶。 選擇您的訂用帳戶,然後選取 [開啟總管]。
檢查輸出佇列
在 Visual Studio Code 中,按 F1 鍵來開啟命令選擇區,然後搜尋並執行
Azure Storage: Open in Storage Explorer
命令,並選擇您的儲存體帳戶名稱。 您的儲存體帳戶會在 Azure 儲存體總管中開啟。展開 [佇列] 節點,然後選取名為 outqueue 的佇列。
佇列包含訊息,該訊息將您執行 HTTP 觸發程序函式時建立的輸出繫結排入佇列。 如果您叫用具有預設
name
值為 Azure 的函式,佇列訊息是:Name passed to the function: Azure。再次執行函式並傳送另一個要求,即會在佇列中看到新的訊息。
現在,您可以將更新的函式應用程式重新發行至 Azure。
重新部署並驗證更新的應用程式
在 Visual Studio Code 中,按 F1 開啟命令選擇區。 在命令選擇區中,搜尋並選取
Azure Functions: Deploy to function app...
。選擇您在第一篇文章中所建立的函式應用程式。 由於您是要將專案部署至相同的應用程式,請選取 [部署] 來關閉關於覆寫檔案的警告。
部署完成之後,您可以再次使用 [立即執行函式] 功能來觸發 Azure 中的函式。
再次檢視儲存體佇列中的訊息,以確認輸出繫結會在佇列中產生新訊息。
清除資源
在 Azure 中,「資源」是指函式應用程式、函式、儲存體帳戶等等。 其會分組為「資源群組」,您可以藉由刪除群組來刪除群組中的所有項目。
您已建立完成這些快速入門所需的資源。 您可能必須支付這些資源,取決於您的帳戶狀態和服務定價。 如果您不再需要資源,刪除方式如下:
在 Visual Studio Code 中,按 F1 開啟命令選擇區。 在命令選擇區中,搜尋並選取
Azure: Open in portal
。選擇您的函數應用程式,並按下 Enter。 函式應用程式頁面會在 Azure 入口網站中開啟。
在 [概觀] 索引標籤中,選取 [資源群組] 旁的具名連結。
在 [資源群組] 分頁上,檢閱所含資源的清單,並確認這些是您想要刪除的項目。
選取 [刪除資源群組],並遵循指示。
刪除需要幾分鐘的時間。 完成時,通知會出現幾秒鐘的時間。 您也可以選取分頁頂端的鈴鐺圖示以檢視通知。
下一步
您已更新 HTTP 觸發的函式,以將資料寫入至儲存體佇列。 現在,您可以深入了解如何使用 Visual Studio Code 來開發 Functions: