Azure Functions verbinden met Azure Storage met behulp van opdrachtregelhulpprogramma's

In dit artikel integreert u een Azure Storage-wachtrij met de functie die en het opslagaccount dat u in het vorige quickstart-artikel hebt gemaakt. De integratie wordt mogelijk gemaakt door uitvoerbinding die gegevens schrijft van een HTTP-aanvraag naar een bericht in de wachtrij. Het voltooien van dit artikel brengt geen extra kosten met zich mee, behalve de paar dollarcent die tijdens de vorige quickstart zijn uitgegeven. Zie Concepten van Azure Functions-triggers en -bindingen voor meer informatie over bindingen.

Notitie

Dit artikel ondersteunt momenteel alleen Node.js v3 voor Functions.

Uw lokale omgeving configureren

Voordat u begint, moet u het artikel Quickstart: Een Azure Functions-project maken vanaf de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Voordat u begint, moet u het artikel Quickstart: Een Azure Functions-project maken vanaf de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Voordat u begint, moet u het artikel Quickstart: Een Azure Functions-project maken vanaf de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Voordat u begint, moet u het artikel Quickstart: Een Azure Functions-project maken vanaf de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Voordat u begint, moet u het artikel Quickstart: Een Azure Functions-project maken vanaf de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Voordat u begint, moet u het artikel Quickstart: Een Azure Functions-project maken vanaf de opdrachtregel. Als u de resources na voltooiing van dat artikel al had opgeruimd, doorloopt u de stappen voor het maken van de functie-app en de bijbehorende resources opnieuw in Azure.

Azure Storage-verbindingsreeks ophalen

Eerder hebt u een Azure Storage-account gemaakt voor het gebruik van de functie-app. De verbindingsreeks voor dit account wordt veilig opgeslagen in de app-instellingen in Azure. Als u de instelling naar het local.settings.json-bestand downloadt, kunt u de verbinding gebruiken om naar een opslagwachtrij in hetzelfde account te schrijven wanneer u de functie lokaal uitvoert.

  1. Voer vanuit de hoofdmap van het project de volgende opdracht uit, vervang deze door <APP_NAME> de naam van uw functie-app uit de vorige stap. Met deze opdracht worden alle bestaande waarden in het bestand overschreven.

    func azure functionapp fetch-app-settings <APP_NAME>
    
  2. Open local.settings.json bestand en zoek de waarde met de naamAzureWebJobsStorage, het opslagaccount verbindingsreeks. U gebruikt de naam AzureWebJobsStorage en de verbindingsreeks in andere secties van dit artikel.

Belangrijk

Omdat het bestand local.settings.json geheimen bevat die zijn gedownload uit Azure, sluit u dit bestand altijd uit van broncodebeheer. Met het bestand .gitignore, dat met een lokaal Functions-project is gemaakt, wordt het bestand standaard uitgesloten.

Binding-extensies registreren

Met uitzondering van HTTP- en timertriggers worden bindingen geïmplementeerd als uitbreidingspakketten. Voer de volgende dotnet add package-opdracht in het terminalvenster uit om het Storage-extensiepakket toe te voegen aan uw project.

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues --prerelease

Nu kunt u de Storage-uitvoerbinding toevoegen aan uw project.

Een definitie van een uitvoerbinding toevoegen aan de functie

Hoewel een functie slechts één trigger kan hebben, kan deze meerdere invoer- en uitvoerbindingen hebben, waarmee u verbinding kunt maken met andere Azure-services en -resources zonder aangepaste integratiecode te schrijven.

U declareert deze bindingen in het bestand function.json in de map function. Door de vorige quickstart bevat uw bestand function.json in de map HttpExample twee bindingen in de verzameling bindings:

Wanneer u het Python v2-programmeermodel gebruikt, worden bindingskenmerken rechtstreeks in het function_app.py-bestand gedefinieerd als decorators. In de vorige quickstart bevat uw function_app.py bestand al één binding op basis van decorator:

import azure.functions as func
import logging

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)

De route decorator voegt httpTrigger- en HttpOutput-binding toe aan de functie, waardoor uw functie kan worden geactiveerd wanneer http-aanvragen de opgegeven route bereiken.

Als u vanuit deze functie naar een Azure Storage-wachtrij wilt schrijven, voegt u de queue_output decorator toe aan uw functiecode:

@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")

Identificeer in de decorator arg_name de bindingsparameter waarnaar wordt verwezen in uw code, queue_name is de naam van de wachtrij waarnaar de binding schrijft en connection is de naam van een toepassingsinstelling die de verbindingsreeks voor het opslagaccount bevat. In quickstarts gebruikt u hetzelfde opslagaccount als de functie-app, die zich in de AzureWebJobsStorage instelling bevindt (uit local.settings.json bestand). Wanneer de queue_name binding niet bestaat, wordt deze gemaakt bij het eerste gebruik.

"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "res"
    }
]
"bindings": [
  {
    "authLevel": "function",
    "type": "httpTrigger",
    "direction": "in",
    "name": "Request",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "Response"
  }
]

De tweede binding in de verzameling heeft de naam res. Deze http-binding is een uitvoerbinding (out) die wordt gebruikt voor het schrijven van het HTTP-antwoord.

Als u vanuit deze functie naar een Azure Storage-wachtrij wilt schrijven, voegt u een out-binding van het type queue met de naam msg toe, zoals wordt weergegeven in de onderstaande code:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

De tweede binding in de verzameling heeft de naam res. Deze http-binding is een uitvoerbinding (out) die wordt gebruikt voor het schrijven van het HTTP-antwoord.

Als u vanuit deze functie naar een Azure Storage-wachtrij wilt schrijven, voegt u een out-binding van het type queue met de naam msg toe, zoals wordt weergegeven in de onderstaande code:

    {
      "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"
    }
  ]
}

In dit geval wordt msg als uitvoerargument aan de functie doorgegeven. Voor een queue type moet u ook de naam van de wachtrij queueName opgeven en de naam opgeven van de Azure Storage-verbinding (uit local.settings.json bestand) in connection.

In een C#-project worden de bindingen gedefinieerd als bindingskenmerken voor de functiemethode. Specifieke definities zijn afhankelijk van of uw app in proces (C#-klassebibliotheek) of in een geïsoleerd werkproces wordt uitgevoerd.

Open het HttpExample.cs projectbestand en voeg de volgende MultiResponse klasse toe:

public class MultiResponse
{
    [QueueOutput("outqueue",Connection = "AzureWebJobsStorage")]
    public string[] Messages { get; set; }
    public HttpResponseData HttpResponse { get; set; }
}

Met de MultiResponse klasse kunt u schrijven naar een opslagwachtrij met de naam outqueue en een HTTP-succesbericht. Er kunnen meerdere berichten naar de wachtrij worden verzonden omdat het QueueOutput kenmerk wordt toegepast op een tekenreeksmatrix.

Met Connection de eigenschap wordt het verbindingsreeks voor het opslagaccount ingesteld. In dit geval kunt u weglaten Connection omdat u al het standaardopslagaccount gebruikt.

In een Java-project worden de bindingen gedefinieerd als bindingsaantekeningen in de functiemethode. Het bestand function.json wordt vervolgens automatisch gegenereerd op basis van deze aantekeningen.

Blader naar de locatie van de functiecode onder src/main/java, open het projectbestand Function.java en voeg de volgende parameter aan de methodedefinitie run toe:

@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") OutputBinding<String> msg

De msg parameter is een OutputBinding<T> type, dat een verzameling tekenreeksen vertegenwoordigt. Deze tekenreeksen worden geschreven als berichten naar een uitvoerbinding wanneer de functie is voltooid. In dit geval is de uitvoer een opslagwachtrij met de naam outqueue. De verbindingsreeks voor het Storage-account wordt ingesteld door de methode connection. U geeft de toepassingsinstelling door die het opslagaccount bevat verbindingsreeks, in plaats van de verbindingsreeks zelf door te geven.

De run methodedefinitie moet er nu uitzien als in het volgende voorbeeld:

@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) {
    ...
}

Zie Concepten van Azure Functions-triggers en -bindingen en Configuratie van de wachtrijuitvoer voor meer informatie over bindingen.

Code toevoegen die gebruikmaakt van de uitvoerbinding

Als de wachtrijbinding is gedefinieerd, kunt u de functie bijwerken om de uitvoerparameter msg te ontvangen en berichten te schrijven naar de wachtrij.

Werk HttpExample\function_app.py bij zodat deze overeenkomt met de volgende code, voeg de msg parameter toe aan de functiedefinitie en msg.set(name) onder de if name: instructie:

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
        )

De parameter msg is een instantie van de azure.functions.Out class. De set methode schrijft een tekenreeksbericht naar de wachtrij. In dit geval wordt deze name doorgegeven aan de functie in de URL-querytekenreeks.

Voeg code toe die het bindingsobject van de uitvoer msg in context.bindings gebruikt om een wachtrijbericht te maken. Voeg deze code toe vóór de instructie context.res.

// Add a message to the Storage queue,
// which is the name passed to the function.
context.bindings.msg = (req.query.name || req.body.name);

Op dit moment kan uw functie er als volgt uitzien:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    if (req.query.name || (req.body && req.body.name)) {
        // Add a message to the Storage queue,
        // which is the name passed to the function.
        context.bindings.msg = (req.query.name || req.body.name);
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

Voeg code toe die het bindingsobject van de uitvoer msg in context.bindings gebruikt om een wachtrijbericht te maken. Voeg deze code toe vóór de instructie context.res.

context.bindings.msg = name;

Op dit moment moet uw functie er als volgt uitzien:

import { AzureFunction, Context, HttpRequest } from "@azure/functions"

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    context.log('HTTP trigger function processed a request.');
    const name = (req.query.name || (req.body && req.body.name));

    if (name) {
        // Add a message to the storage queue, 
        // which is the name passed to the function.
        context.bindings.msg = name; 
        // Send a "hello" response.
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

export default httpTrigger;

Voeg code toe die gebruikmaakt van de cmdlet Push-OutputBinding om tekst te schrijven naar de wachtrij met de uitvoerbinding msg. Voeg deze code toe voordat u de status Ok in de instructie if instelt.

$outputMsg = $name
Push-OutputBinding -name msg -Value $outputMsg

Op dit moment moet uw functie er als volgt uitzien:

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
})

Vervang de bestaande HttpExample klasse door de volgende code:

    [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
        };
    }
}

U kunt nu de nieuwe parameter, msg, gebruiken om naar de uitvoerbinding van uw functiecode te schrijven. Voordat u het antwoord krijgt dat de bewerking is geslaagd, voegt u de volgende regel code toe om de waarde van name aan de msg-uitvoerbinding toe te voegen.

msg.setValue(name);

Als u een uitvoerbinding gebruikt, hoeft u niet de Azure Storage SDK-code voor verificatie te gebruiken, een wachtrijverwijzing op te halen of gegevens te schrijven. Deze taken worden voor u verwerkt via Functions-runtime en Queue Storage-uitvoerbinding.

Uw run methode moet er nu uitzien als in het volgende voorbeeld:

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();
    }
}

De tests bijwerken

Omdat het archetype ook een reeks tests maakt, moet u deze tests bijwerken om de nieuwe parameter msg in de handtekening van methode run te verwerken.

Blader naar de locatie van uw testcode onder src/test/java, open het Function.java projectbestand en vervang de coderegel onder //Invoke de volgende code:

@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
final HttpResponseMessage ret = new Function().run(req, msg, context);

Houd er rekening mee dat u geen code hoeft te schrijven voor verificatie, het ophalen van een wachtrijverwijzing of het schrijven van gegevens. Al deze integratietaken kunnen worden verwerkt in de Azure Functions-runtime en in de wachtrijuitvoerbinding.

De functie lokaal uitvoeren

  1. Voer uw functie uit door de lokale Azure Functions-runtimehost te starten vanuit de map LocalFunctionProj .

    func start
    

    Aan het einde van de uitvoer moeten de volgende regels worden weergegeven:

    Schermopname van uitvoer van terminalvensters wanneer u de functie lokaal uitvoert.

    Notitie

    Als HttpExample niet verschijnt zoals hierboven weergegeven, hebt u waarschijnlijk de host gestart van buiten de hoofdmap van het project. In dat geval gebruikt u Ctrl+C om de host te stoppen, naar de hoofdmap van het project te gaan en de vorige opdracht opnieuw uit te voeren.

  2. Kopieer de URL van uw HTTP-functie van deze uitvoer naar een browser en voeg de querytekenreeks ?name=<YOUR_NAME>toe, waardoor de volledige URL er als http://localhost:7071/api/HttpExample?name=Functionsvolgt uitziet. In de browser moet een antwoordbericht worden weergegeven dat de waarde van de querytekenreeks weergeeft. De terminal waarin u uw project hebt gestart, toont ook de logboek uitvoer wanneer u aanvragen doet.

  3. Wanneer u klaar bent, drukt u op Ctrl+C en typt y u om de functiehost te stoppen.

Tip

Tijdens het opstarten downloadt en installeert de host de Storage-bindingsextensie en andere Microsoft-bindingsextensies. Deze installatie vindt plaats omdat bindingsextensies standaard zijn ingeschakeld in het host. json-bestand met de volgende eigenschappen:

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[1.*, 2.0.0)"
    }
}

Als u fouten ondervindt met bindingsextensies, controleert u of host. json de bovenstaande eigenschappen bevat.

Het bericht weergeven in de wachtrij van Azure Storage

U kunt de wachtrij bekijken in de Azure Portal of in de Microsoft Azure Storage Explorer. U kunt de wachtrij ook bekijken in de Azure CLI, zoals wordt beschreven in de volgende stappen:

  1. Open het bestand local.setting.json van het functieproject en kopieer de verbindingsreekswaarde. Voer in een terminal- of opdrachtvenster de volgende opdracht uit om een omgevingsvariabele met de naam AZURE_STORAGE_CONNECTION_STRINGte maken en plak uw specifieke verbindingsreeks in plaats van <MY_CONNECTION_STRING>. (Deze omgevingsvariabele zorgt ervoor dat u de verbindingsreeks niet hoeft op te geven bij elke volgende opdracht met het argument --connection-string.)

    export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
    
  2. (Optioneel) Gebruik de opdracht az storage queue list om de opslagwachtrijen in uw account te bekijken. De uitvoer van deze opdracht moet een wachtrij met de naam outqueuebevatten, die is gemaakt toen de functie het eerste bericht naar die wachtrij schreef.

    az storage queue list --output tsv
    
  3. Gebruik de az storage message get opdracht om het bericht uit deze wachtrij te lezen. Dit moet de waarde zijn die u hebt opgegeven bij het testen van de functie eerder. Met deze opdracht leest en verwijdert u het eerste bericht in de wachtrij.

    echo `echo $(az storage message get --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`
    

    Omdat de berichttekst base64-gecodeerd is opgeslagen, moet het bericht worden gedecodeerd voordat het kan worden weergegeven. Nadat u az storage message get hebt uitgevoerd, wordt het bericht uit de wachtrij verwijderd. Als er slechts één bericht in outqueue was, wordt er geen bericht weergegeven wanneer u deze opdracht een tweede keer uitvoert en wordt in plaats daarvan een foutmelding weergegeven.

Het project opnieuw implementeren in Azure

Nu u lokaal hebt gecontroleerd of de functie een bericht naar de Azure Storage-wachtrij heeft geschreven, kunt u uw project opnieuw implementeren om het eindpunt in Azure bij te werken.

Gebruik in de map LocalFunctionsProj de opdracht func azure functionapp publish om het project opnieuw te implementeren, waarbij u <APP_NAME> vervangt door de naam van uw app.

func azure functionapp publish <APP_NAME>

Gebruik in de lokale projectmap de volgende Maven-opdracht om het project opnieuw te publiceren:

mvn azure-functions:deploy

Verifiëren in Azure

  1. Net als in de vorige quickstart gebruikt u een browser of CURL om de opnieuw geïmplementeerde functie te testen.

    Kopieer de volledige Aanroep-URL die wordt weergegeven in de uitvoer van de publicatieopdracht naar de adresbalk van een browser en voeg de queryparameter &name=Functions toe. In de browser moet dezelfde uitvoer worden weergegeven als toen u de functie lokaal uitvoerde.

  2. Controleer de opslagwachtrij opnieuw, zoals beschreven in de vorige sectie, om te controleren of deze het nieuwe bericht bevat dat naar de wachtrij is geschreven.

Resources opschonen

Wanneer u klaar bent, gebruikt u de volgende opdracht om de resourcegroep en alle bijbehorende resources te verwijderen om te voorkomen dat er verdere kosten in rekening worden gebracht.

az group delete --name AzureFunctionsQuickstart-rg

Volgende stappen

U hebt uw HTTP-geactiveerde functie bijgewerkt om gegevens naar een opslagwachtrij te schrijven. U kunt nu meer te weten komen over het ontwikkelen van functies via de opdrachtregel door gebruik te maken van Core Tools en de Azure CLI: