Ansluta Azure Functions till Azure Storage med hjälp av kommandoradsverktyg
I den här artikeln integrerar du en Azure Storage-kö med funktionen och lagringskontot som du skapade i föregående snabbstartsartikel. Du uppnår den här integreringen med hjälp av en utdatabindning som skriver data från en HTTP-begäran till ett meddelande i kön. Att slutföra den här artikeln medför inga ytterligare kostnader utöver de få USD-centen i föregående snabbstart. Mer information om bindningar finns i Azure Functions-utlösare och bindningar.
Konfigurera din lokala miljö
Innan du börjar måste du slutföra artikeln Snabbstart: Skapa ett Azure Functions-projekt från kommandoraden. Om du redan har rensat resurser i slutet av den artikeln går du igenom stegen igen för att återskapa funktionsappen och relaterade resurser i Azure.
Innan du börjar måste du slutföra artikeln Snabbstart: Skapa ett Azure Functions-projekt från kommandoraden. Om du redan har rensat resurser i slutet av den artikeln går du igenom stegen igen för att återskapa funktionsappen och relaterade resurser i Azure.
Innan du börjar måste du slutföra artikeln Snabbstart: Skapa ett Azure Functions-projekt från kommandoraden. Om du redan har rensat resurser i slutet av den artikeln går du igenom stegen igen för att återskapa funktionsappen och relaterade resurser i Azure.
Innan du börjar måste du slutföra artikeln Snabbstart: Skapa ett Azure Functions-projekt från kommandoraden. Om du redan har rensat resurser i slutet av den artikeln går du igenom stegen igen för att återskapa funktionsappen och relaterade resurser i Azure.
Innan du börjar måste du slutföra artikeln Snabbstart: Skapa ett Azure Functions-projekt från kommandoraden. Om du redan har rensat resurser i slutet av den artikeln går du igenom stegen igen för att återskapa funktionsappen och relaterade resurser i Azure.
Innan du börjar måste du slutföra artikeln Snabbstart: Skapa ett Azure Functions-projekt från kommandoraden. Om du redan har rensat resurser i slutet av den artikeln går du igenom stegen igen för att återskapa funktionsappen och relaterade resurser i Azure.
Hämta Azure Storage-niska veze
Tidigare skapade du ett Azure Storage-konto för funktionsappens användning. Niska veze för det här kontot lagras på ett säkert sätt i appinställningarna i Azure. Genom att ladda ned inställningen till local.settings.json-filen kan du använda anslutningen för att skriva till en lagringskö i samma konto när du kör funktionen lokalt.
Kör följande kommando från projektets rot och ersätt
<APP_NAME>
med namnet på funktionsappen från föregående steg. Det här kommandot skriver över alla befintliga värden i filen.func azure functionapp fetch-app-settings <APP_NAME>
Öppna local.settings.json fil och leta upp värdet med namnet
AzureWebJobsStorage
, vilket är lagringskontot niska veze. Du använder namnetAzureWebJobsStorage
och niska veze i andra avsnitt i den här artikeln.
Viktigt!
Eftersom den local.settings.json filen innehåller hemligheter som laddats ned från Azure utesluter du alltid den här filen från källkontrollen. Den .gitignore-fil som skapats med ett lokalt funktionsprojekt exkluderar filen som standard.
Registrera bindningstillägg
Förutom HTTP- och timerutlösare implementeras bindningar som tilläggspaket. Kör följande dotnet add package-kommando i terminalfönstret för att lägga till lagringstilläggspaketet i projektet.
dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues --prerelease
Nu kan du lägga till bindningen för lagringsutdata i projektet.
Lägga till en utdatabindningsdefinition i funktionen
Även om en funktion bara kan ha en utlösare kan den ha flera indata- och utdatabindningar, vilket gör att du kan ansluta till andra Azure-tjänster och resurser utan att skriva anpassad integreringskod.
När du använder programmeringsmodellen Node.js v4 definieras bindningsattribut direkt i filen ./src/functions/HttpExample.js . Från föregående snabbstart innehåller filen redan en HTTP-bindning som definierats av app.http
metoden.
const { app } = require('@azure/functions');
app.http('httpTrigger', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
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) {
return { status: 404, body: 'Not Found' };
}
return { body: `Hello, ${name}!` };
} catch (error) {
context.log(`Error: ${error}`);
return { status: 500, body: 'Internal Server Error' };
}
},
});
När du använder programmeringsmodellen Node.js v4 definieras bindningsattribut direkt i filen ./src/functions/HttpExample.js . Från föregående snabbstart innehåller filen redan en HTTP-bindning som definierats av app.http
metoden.
import {
app,
HttpRequest,
HttpResponseInit,
InvocationContext,
} from '@azure/functions';
export async function httpTrigger1(
request: HttpRequest,
context: InvocationContext,
): Promise<HttpResponseInit> {
context.log(`Http function processed request for url "${request.url}"`);
const name = request.query.get('name') || (await request.text()) || 'world';
return { body: `Hello, ${name}!` };
}
app.http('httpTrigger1', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
handler: httpTrigger1,
});
Du deklarerar dessa bindningar i function.json-filen i funktionsmappen. Från föregående snabbstart innehåller din function.json-fil i mappen HttpExample två bindningar i bindings
samlingen:
När du använder programmeringsmodellen Python v2 definieras bindningsattribut direkt i den function_app.py filen som dekoratörer. Från föregående snabbstart innehåller din function_app.py-fil redan en dekoratörsbaserad bindning:
import azure.functions as func
import logging
app = func.FunctionApp()
@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)
Dekoratören route
lägger till HttpTrigger- och HttpOutput-bindning till funktionen, vilket gör att funktionen kan utlösas när http-begäranden når den angivna vägen.
Om du vill skriva till en Azure Storage-kö från den här funktionen lägger du till dekoratören i queue_output
funktionskoden:
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
I dekoratören arg_name
identifierar du bindningsparametern som refereras till i koden, queue_name
är namnet på kön som bindningen skriver till och connection
är namnet på en programinställning som innehåller niska veze för Lagringskontot. I snabbstarter använder du samma lagringskonto som funktionsappen AzureWebJobsStorage
, som finns i inställningen (från local.settings.json fil). När inte queue_name
finns skapar bindningen den vid första användningen.
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "Request",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "Response"
}
]
Så här skriver du till en Azure Storage-kö:
Lägga till en
extraOutputs
egenskap i bindningskonfigurationen{ methods: ['GET', 'POST'], extraOutputs: [sendToQueue], // add output binding to HTTP trigger authLevel: 'anonymous', handler: () => {} }
Lägg till en
output.storageQueue
funktion ovanför anropetapp.http
const sendToQueue: StorageQueueOutput = output.storageQueue({ queueName: 'outqueue', connection: 'AzureWebJobsStorage', });
Den andra bindningen i samlingen heter res
. Den här http
bindningen är en utdatabindning (out
) som används för att skriva HTTP-svaret.
Om du vill skriva till en Azure Storage-kö från den här funktionen lägger du till en out
bindning av typen queue
med namnet msg
, enligt koden nedan:
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "Request",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "Response"
},
{
"type": "queue",
"direction": "out",
"name": "msg",
"queueName": "outqueue",
"connection": "AzureWebJobsStorage"
}
]
}
För en queue
typ måste du ange namnet på kön i queueName
och ange namnet på Azure Storage-anslutningen (från local.settings.json-filen ) i connection
.
I ett C#-projekt definieras bindningarna som bindningsattribut för funktionsmetoden. Specifika definitioner beror på om din app körs i processen (C#-klassbiblioteket) eller i en isolerad arbetsprocess.
Öppna HttpExample.cs-projektfilen och lägg till följande MultiResponse
klass:
public class MultiResponse
{
[QueueOutput("outqueue",Connection = "AzureWebJobsStorage")]
public string[] Messages { get; set; }
public HttpResponseData HttpResponse { get; set; }
}
Med MultiResponse
klassen kan du skriva till en lagringskö med namnet outqueue
och ett HTTP-meddelande. Flera meddelanden kan skickas till kön eftersom QueueOutput
attributet tillämpas på en strängmatris.
Egenskapen Connection
anger niska veze för lagringskontot. I det här fallet kan du utelämna Connection
eftersom du redan använder standardlagringskontot.
I ett Java-projekt definieras bindningarna som bindningsanteckningar för funktionsmetoden. Filen function.json genereras sedan automatiskt baserat på dessa anteckningar.
Bläddra till platsen för funktionskoden under src/main/java, öppna projektfilen Function.java och lägg till följande parameter i metoddefinitionen run
:
@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") OutputBinding<String> msg
Parametern msg
är en OutputBinding<T>
typ som representerar en samling strängar. Dessa strängar skrivs som meddelanden till en utdatabindning när funktionen är klar. I det här fallet är utdata en lagringskö med namnet outqueue
. Niska veze för lagringskontot anges med connection
metoden . Du skickar programinställningen som innehåller lagringskontot niska veze i stället för att skicka själva niska veze.
Metoddefinitionen run
måste nu se ut som i följande exempel:
@FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
@HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)
HttpRequestMessage<Optional<String>> request,
@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage")
OutputBinding<String> msg, final ExecutionContext context) {
...
}
Mer information om bindningar finns i Azure Functions-utlösare och bindningar och konfiguration av köutdata.
Lägg till kod för att använda utdatabindningen
Med köbindningen definierad kan du nu uppdatera funktionen för att ta emot msg
utdataparametern och skriva meddelanden till kön.
Uppdatera HttpExample\function_app.py för att matcha följande kod, lägg till parametern msg
i funktionsdefinitionen och msg.set(name)
under -instruktionen 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
)
Parametern msg
är en instans av azure.functions.Out class
. Metoden set
skriver ett strängmeddelande till kön. I det här fallet skickas den name
till funktionen i URL-frågesträngen.
Lägg till kod som använder utdatabindningsobjektet på context.extraOutputs
för att skapa ett kömeddelande. Lägg till den här koden före retur-instruktionen.
context.extraOutputs.set(sendToQueue, [msg]);
I det här läget kan funktionen se ut så här:
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' };
}
},
});
Lägg till kod som använder utdatabindningsobjektet på context.extraOutputs
för att skapa ett kömeddelande. Lägg till den här koden före retur-instruktionen.
context.extraOutputs.set(sendToQueue, [msg]);
I det här läget kan funktionen se ut så här:
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,
});
Lägg till kod som använder cmdleten Push-OutputBinding
för att skriva text till kön med hjälp av utdatabindningen msg
. Lägg till den här koden innan du anger OK-status i -instruktionen if
.
$outputMsg = $name
Push-OutputBinding -name msg -Value $outputMsg
I det här läget måste funktionen se ut så här:
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
})
Ersätt den befintliga HttpExample
klassen med följande kod:
[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
};
}
}
Nu kan du använda den nya msg
parametern för att skriva till utdatabindningen från funktionskoden. Lägg till följande kodrad före det lyckade svaret för att lägga till värdet name
för i utdatabindningen msg
.
msg.setValue(name);
När du använder en utdatabindning behöver du inte använda Azure Storage SDK-koden för autentisering, hämta en köreferens eller skriva data. Functions runtime- och köutdatabindning utför dessa uppgifter åt dig.
Metoden run
måste nu se ut som i följande exempel:
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();
}
}
Uppdatera testerna
Eftersom arketypen också skapar en uppsättning tester måste du uppdatera dessa tester för att hantera den nya msg
parametern i metodsignaturen run
.
Bläddra till platsen för testkoden under src/test/java, öppna Function.java projektfilen och ersätt kodraden under //Invoke
med följande kod:
@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
final HttpResponseMessage ret = new Function().run(req, msg, context);
Observera att du inte behöver skriva någon kod för autentisering, hämta en köreferens eller skriva data. Alla dessa integreringsuppgifter hanteras enkelt i Azure Functions-körnings- och köutdatabindningen.
Kör funktionen lokalt
Kör funktionen genom att starta den lokala Azure Functions-körningsvärden från mappen LocalFunctionProj .
func start
Mot slutet av utdata måste följande rader visas:
Kommentar
Om HttpExample inte visas som ovan startade du förmodligen värden utanför rotmappen i projektet. I så fall använder du Ctrl+C för att stoppa värden, går till projektets rotmapp och kör föregående kommando igen.
Kopiera URL:en för HTTP-funktionen från den här utdatan till en webbläsare och lägg till frågesträngen
?name=<YOUR_NAME>
, vilket gör den fullständiga URL:en till exempelhttp://localhost:7071/api/HttpExample?name=Functions
. Webbläsaren bör visa ett svarsmeddelande som upprepar frågesträngsvärdet. Terminalen där du startade projektet visar även loggutdata när du gör begäranden.När du är klar trycker du på Ctrl + C och skriver
y
för att stoppa funktionsvärden.
Dricks
Under starten laddar värden ned och installerar lagringsbindningstillägget och andra Microsoft-bindningstillägg. Den här installationen sker eftersom bindningstillägg är aktiverade som standard i filen host.json med följande egenskaper:
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}
Om du stöter på fel som rör bindningstillägg kontrollerar du att egenskaperna ovan finns i host.json.
Visa meddelandet i Azure Storage-kön
Du kan visa kön i Azure-portalen eller i Microsoft Azure Storage Explorer. Du kan också visa kön i Azure CLI enligt beskrivningen i följande steg:
Öppna funktionsprojektets local.setting.json-fil och kopiera värdet för niska veze. I ett terminal- eller kommandofönster kör du följande kommando för att skapa en miljövariabel med namnet
AZURE_STORAGE_CONNECTION_STRING
och klistra in din specifika niska veze i stället för<MY_CONNECTION_STRING>
. (Den här miljövariabeln innebär att du inte behöver ange niska veze till varje efterföljande kommando med argumentet--connection-string
.)export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
(Valfritt)
az storage queue list
Använd kommandot för att visa lagringsköerna i ditt konto. Utdata från det här kommandot måste innehålla en kö med namnetoutqueue
, som skapades när funktionen skrev sitt första meddelande till kön.az storage queue list --output tsv
az storage message get
Använd kommandot för att läsa meddelandet från den här kön, vilket bör vara det värde som du angav när du testade funktionen tidigare. Kommandot läser och tar bort det första meddelandet från kön.echo `echo $(az storage message get --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`
Eftersom meddelandetexten lagras base64-kodad måste meddelandet avkodas innan det visas. När du har kört
az storage message get
tas meddelandet bort från kön. Om det bara fanns ett meddelande ioutqueue
hämtar du inte ett meddelande när du kör det här kommandot en andra gång och får i stället ett fel.
Distribuera om projektet till Azure
Nu när du har verifierat lokalt att funktionen skrev ett meddelande till Azure Storage-kön kan du distribuera om projektet för att uppdatera slutpunkten som körs i Azure.
I mappen LocalFunctionsProj använder du func azure functionapp publish
kommandot för att distribuera om projektet och ersätter<APP_NAME>
med namnet på din app.
func azure functionapp publish <APP_NAME>
I den lokala projektmappen använder du följande Maven-kommando för att publicera om projektet:
mvn azure-functions:deploy
Verifiera i Azure
Precis som i föregående snabbstart använder du en webbläsare eller CURL för att testa den omdistribuerade funktionen.
Kopiera den fullständiga Anropa URL:en som visas i utdata från publiceringskommandot till ett webbläsaradressfält och lägga till frågeparametern
&name=Functions
. Webbläsaren bör visa samma utdata som när du körde funktionen lokalt.Granska lagringskö igen, enligt beskrivningen i föregående avsnitt, för att kontrollera att den innehåller det nya meddelandet som skrivits till kön.
Rensa resurser
När du är klar använder du följande kommando för att ta bort resursgruppen och alla dess inneslutna resurser för att undvika ytterligare kostnader.
az group delete --name AzureFunctionsQuickstart-rg
Nästa steg
Du har uppdaterat din HTTP-utlösta funktion för att skriva data till en lagringskö. Nu kan du lära dig mer om att utveckla Functions från kommandoraden med Core Tools och Azure CLI: