Menyambungkan Azure Functions ke Azure Storage menggunakan alat baris perintah

Dalam artikel ini, Anda mengintegrasikan antrean Azure Storage dengan fungsi dan akun penyimpanan yang Anda buat di artikel mulai cepat sebelumnya. Anda mencapai integrasi ini dengan menggunakan pengikatan output yang menulis data dari permintaan HTTP ke pesan dalam antrean. Menyelesaikan artikel ini tidak dikenakan biaya tambahan melebihi beberapa sen USD dari mulai cepat sebelumnya. Untuk mempelajari lebih lanjut, lihat konsep pemicu dan pengikatan Azure Functions.

Mengkonfigurasikan lingkungan lokal Anda

Sebelum memulai, Anda harus menyelesaikan artikel, Mulai Cepat: Membuat proyek Azure Functions dari baris perintah. Jika Anda sudah membersihkan sumber daya di akhir artikel tersebut, lakukan lagi langkah-langkahnya untuk membuat ulang aplikasi fungsi dan sumber daya terkait di Azure.

Sebelum memulai, Anda harus menyelesaikan artikel, Mulai Cepat: Membuat proyek Azure Functions dari baris perintah. Jika Anda sudah membersihkan sumber daya di akhir artikel tersebut, lakukan lagi langkah-langkahnya untuk membuat ulang aplikasi fungsi dan sumber daya terkait di Azure.

Sebelum memulai, Anda harus menyelesaikan artikel, Mulai Cepat: Membuat proyek Azure Functions dari baris perintah. Jika Anda sudah membersihkan sumber daya di akhir artikel tersebut, lakukan lagi langkah-langkahnya untuk membuat ulang aplikasi fungsi dan sumber daya terkait di Azure.

Sebelum memulai, Anda harus menyelesaikan artikel, Mulai Cepat: Membuat proyek Azure Functions dari baris perintah. Jika Anda sudah membersihkan sumber daya di akhir artikel tersebut, lakukan lagi langkah-langkahnya untuk membuat ulang aplikasi fungsi dan sumber daya terkait di Azure.

Sebelum memulai, Anda harus menyelesaikan artikel, Mulai Cepat: Membuat proyek Azure Functions dari baris perintah. Jika Anda sudah membersihkan sumber daya di akhir artikel tersebut, lakukan lagi langkah-langkahnya untuk membuat ulang aplikasi fungsi dan sumber daya terkait di Azure.

Sebelum memulai, Anda harus menyelesaikan artikel, Mulai Cepat: Membuat proyek Azure Functions dari baris perintah. Jika Anda sudah membersihkan sumber daya di akhir artikel tersebut, lakukan lagi langkah-langkahnya untuk membuat ulang aplikasi fungsi dan sumber daya terkait di Azure.

Mengambil string koneksi Azure Storage

Sebelumnya, Anda telah membuat akun Azure Storage untuk digunakan oleh aplikasi fungsi. String koneksi untuk akun ini disimpan dengan aman di pengaturan aplikasi di Azure. Dengan mengunduh pengaturan ke dalam file local.settings.json, Anda bisa menggunakan menulis koneksi tersebut ke Antrean penyimpanan di akun yang sama saat menjalankan fungsi secara lokal.

  1. Dari akar proyek, jalankan perintah berikut, ganti <APP_NAME> dengan nama aplikasi fungsi Anda dari mulai cepat yang sebelumnya. Perintah ini akan menimpa setiap nilai yang ada pada file.

    func azure functionapp fetch-app-settings <APP_NAME>
    
  2. Buka local.settings.json lalu temukan nilai bernama AzureWebJobsStorage, yang merupakan string koneksi akun Azure Storage. Anda menggunakan nama AzureWebJobsStorage dan string koneksi di bagian lain artikel ini.

Penting

Karena local.settings.json berisi rahasia yang diunduh dari Azure, harap selalu kecualikan file ini dari kontrol sumber. File .gitignore yang dibuat dengan proyek fungsi lokal mengecualikan file secara default.

Mendaftarkan ekstensi pengikatan

Kecuali untuk pemicu HTTP dan timer, pengikatan diimplementasikan sebagai paket ekstensi. Jalankan perintah dotnet add package berikut di jendela Terminal untuk menambahkan paket ekstensi Azure Storage ke proyek Anda.

dotnet add package Microsoft.Azure.WebJobs.Extensions.Storage 

Sekarang, Anda dapat menambahkan pengikatan output penyimpanan ke proyek Anda.

Menambahkan definisi pengikatan output ke fungsi

Meskipun fungsi hanya bisa memiliki satu pemicu, fungsi ini dapat memiliki beberapa pengikatan input dan output, yang memungkinkan Anda terhubung ke layanan dan sumber daya Azure lainnya tanpa menulis kode integrasi kustom.

Anda mendeklarasikan pengikatan ini di file function.json di folder fungsi Anda. Dari mulai cepat sebelumnya, file function.json di folder HttpExample berisi dua pengikatan dalam koleksi bindings:

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

Setiap pengikatan memiliki setidaknya jenis, arah, dan nama. Pada contoh di atas, pengikatan pertama berjenis httpTrigger dengan arah in. Untuk arah in, name menentukan nama parameter input yang dikirim ke fungsi saat dipanggil oleh pemicu.

Pengikatan kedua dalam koleksi diberi nama res. Pengikatan http ini adalah pengikatan output (out) yang digunakan untuk menulis respons HTTP.

Untuk menulis ke antrean Azure Storage dari fungsi ini, tambahkan pengikatan out jenis queue dengan nama msg, seperti yang ditunjukkan pada kode di bawah ini:

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

Pengikatan kedua dalam koleksi berjenis http dengan arah out, yang merupakan name khusus dari $return menunjukkan bahwa pengikatan ini menggunakan nilai pengembalian fungsi daripada memberikan parameter input.

Untuk menulis ke antrean Azure Storage dari fungsi ini, tambahkan pengikatan out jenis queue dengan nama msg, seperti yang ditunjukkan pada kode di bawah ini:

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

Pengikatan kedua dalam koleksi diberi nama res. Pengikatan http ini adalah pengikatan output (out) yang digunakan untuk menulis respons HTTP.

Untuk menulis ke antrean Azure Storage dari fungsi ini, tambahkan pengikatan out jenis queue dengan nama msg, seperti yang ditunjukkan pada kode di bawah ini:

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

Dalam hal ini, msg diberikan kepada fungsi sebagai argumen output. Untuk jenis queue, Anda juga harus menentukan nama antrean di queueName serta memberikan nama koneksi Azure Storage (dari local.settings.json) di connection.

Dalam proyek C#, pengikatan didefinisikan sebagai atribut pengikatan pada metode fungsi. Definisi spesifik bergantung pada apakah aplikasi Anda berjalan dalam proses (pustaka kelas C # ) atau dalam proses yang terisolasi.

Buka file proyek HttpExample.cs dan tambahkan parameter berikut ke definisi metode Run:

[Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg,

Parameter msg adalah jenis ICollector<T>, yang mewakili kumpulan pesan yang ditulis ke pengikatan data output saat fungsi selesai. Dalam hal ini, output adalah antrean penyimpanan `bernama outqueue. StorageAccountAttribute mengatur string koneksi pada akun penyimpanan. Atribut ini menunjukkan pengaturan yang berisi string koneksi pada akun penyimpanan dan dapat diterapkan di tingkat kelas, metode, atau parameter. Dalam hal ini, Anda dapat mengabaikan StorageAccountAttribute karena Anda sudah menggunakan akun penyimpanan default.

Definisi metode Run sekarang akan terlihat seperti kode berikut:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)

Dalam proyek Java, pengikatan didefinisikan sebagai anotasi pengikatan pada metode fungsi. Daftar file function.json kemudian dibuat secara otomatis berdasarkan anotasi ini.

Telusuri ke lokasi kode fungsi Anda di src/main/java, buka file proyek Function.java, dan tambahkan parameter berikut ke definisi metode run:

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

Parameter msg adalah tipe OutputBinding<T>, yang mewakili kumpulan string. String ini ditulis sebagai pesan ke output yang mengikat saat fungsi selesai. Dalam hal ini, output adalah antrean penyimpanan `bernama outqueue. String koneksi untuk akun Storage diatur sesuai metode connection. Anda melewati pengaturan aplikasi yang berisi string koneksi akun Penyimpanan, daripada meneruskan string koneksi itu sendiri.

Definisi metode run sekarang harus terlihat seperti contoh berikut:

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

Untuk informasi selengkapnya tentang detail pengikatan, lihat konsep pemicu dan pengikatan Azure Functions dan konfigurasi output antrean.

Menambahkan kode untuk menggunakan pengikatan output

Dengan pengikatan antrean yang ditentukan, Anda sekarang dapat memperbarui fungsi Anda untuk msg menerima parameter output dan menulis pesan ke antrean.

Perbarui HttpExample\__init__.py agar sesuai dengan kode berikut, harap tambahkan parameter msg ke definisi fungsi dan msg.set(name) di bawah pernyataan if name::

import logging

import azure.functions as func


def main(req: func.HttpRequest, msg: func.Out[func.QueueMessage]) -> str:

    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}!")
    else:
        return func.HttpResponse(
            "Please pass a name on the query string or in the request body",
            status_code=400
        )

Parameter msg adalah instans dari azure.functions.Out class. Metode set menuliskan pesan string pada antrean. Dalam hal ini, pesannya merupakan nama yang diteruskan pada fungsi dalam string kueri URL.

Tambahkan kode yang menggunakan objek pengikatan output msg pada context.bindings untuk membuat pesan antrean. Tambahkan kode ini sebelum pernyataan 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);

Pada titik ini, fungsi Anda akan ditampilkan sebagai berikut:

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

Tambahkan kode yang menggunakan objek pengikatan output msg pada context.bindings untuk membuat pesan antrean. Tambahkan kode ini sebelum pernyataan context.res.

context.bindings.msg = name;

Pada titik ini, fungsi Anda akan ditampilkan sebagai berikut:

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;

Tambahkan kode yang menggunakan Push-OutputBinding cmdlet untuk menulis teks ke antrean menggunakan pengikatan output msg. Tambahkan kode ini sebelum Anda mengatur status OK dalam pernyataan if.

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

Pada titik ini, fungsi Anda akan ditampilkan sebagai berikut:

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

Tambahkan kode yang menggunakan objek pengikatan output msg untuk membuat pesan antrean. Tambahkan kode ini sebelum metode kembali.

if (!string.IsNullOrEmpty(name))
{
    // Add a message to the output collection.
    msg.Add(name);
}

Pada titik ini, fungsi Anda akan ditampilkan sebagai berikut:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];

    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    if (!string.IsNullOrEmpty(name))
    {
        // Add a message to the output collection.
        msg.Add(name);
    }
    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

Sekarang, Anda dapat menggunakan parameter msg baru untuk menulis ke pengikatan output dari kode fungsi Anda. Tambahkan garis kode berikut sebelum respons keberhasilan untuk menambahkan nilai name ke pengikatan output msg.

msg.setValue(name);

Saat menggunakan pengikatan output, Anda tidak perlu menggunakan kode SDK Azure Storage untuk mengautentikasi, mendapatkan referensi antrean, atau menulis data. Runtime Functions dan pengikatan output antrean akan melakukan tugas-tugas tersebut untuk Anda.

Metode run Anda sekarang harus terlihat seperti contoh berikut:

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

Perbarui tes

Karena arketipe juga membuat kumpulan pengujian, Anda perlu memperbarui pengujian ini untuk menangani parameter msg baru di tanda tangan metode run.

Telusuri lokasi kode pengujian Anda di bawah src/test/java, buka file proyek Function.java, dan ganti baris kode di bawah //Invoke dengan kode berikut:

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

Amati bahwa Anda tidak perlu menulis kode apa pun untuk autentikasi, mendapatkan referensi antrean, atau menulis data. Semua tugas integrasi ini ditangani dengan mudah dalam runtime Azure Functions dan pengikatan output antrean.

Menjalankan fungsi secara lokal

  1. Jalankan fungsi Anda dengan memulai host runtime Azure Functions lokal dari folder LocalFunctionProj.

    func start
    

    Menjelang akhir output, baris berikut harus muncul:

     ...
    
     Now listening on: http://0.0.0.0:7071
     Application started. Press Ctrl+C to shut down.
    
     Http Functions:
    
             HttpExample: [GET,POST] http://localhost:7071/api/HttpExample
     ...
    
     

    Catatan

    Jika HttpExample tidak muncul seperti yang ditunjukkan di atas, Anda mungkin memulai hosting dari luar folder akar proyek. Dalam kasus tersebut, gunakan Ctrl+C untuk menghentikan hosting, buka folder akar proyek, dan jalankan kembali perintah sebelumnya.

  2. Salin URL fungsi HttpExample Anda dari output ini ke browser dan tambahkan string kueri ?name=<YOUR_NAME>, membuat URL lengkap seperti http://localhost:7071/api/HttpExample?name=Functions. Browser akan menampilkan pesan tanggapan yang mengulang nilai string kueri Anda. Terminal tempat Anda memulai proyek juga menunjukkan output log saat Anda membuat permintaan.

  3. Jika sudah selesai, tekan Ctrl + C dan ketik y untuk menghentikan hosting fungsi.

Tip

Selama startup, host mengunduh dan menginstal ekstensi pengikatan Penyimpanan dan ekstensi pengikatan Microsoft lainnya. Penginstalan ini terjadi karena ekstensi pengikatan diaktifkan secara default di file host.json dengan properti berikut:

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

Jika Anda mengalami kesalahan yang terkait dengan ekstensi pengikatan, periksa apakah properti di atas ada di host.json.

Menampilkan pesan dalam antrean Azure Storage

Anda dapat melihat antrean di portal Azure atau di Microsoft Azure Storage Explorer. Anda juga bisa melihat antrean di Azure CLI, seperti yang dijelaskan dalam langkah-langkah berikut:

  1. Buka file local.setting.json proyek fungsi dan salin nilai string koneksi. Di terminal atau jendela perintah, jalankan perintah berikut guna membuat variabel lingkungan bernama AZURE_STORAGE_CONNECTION_STRING, menempelkan string koneksi spesifik Anda untuk menggantikan <MY_CONNECTION_STRING>. (Variabel lingkungan ini berarti Anda tidak perlu menyediakan string koneksi ke setiap perintah berikutnya menggunakan argumen --connection-string.)

    export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
    
  2. (Opsional) Gunakan perintah az storage queue list untuk melihat antrean Storage di akun Anda. Output dari perintah ini harus mencakup antrian bernama outqueue, yang dibuat ketika fungsi menulis pesan pertamanya pada antrean tersebut.

    az storage queue list --output tsv
    
  3. Gunakan perintah az storage message get untuk membaca pesan dari antrean ini, yang seharusnya menjadi nilai yang Anda sediakan saat menguji fungsi sebelumnya. Perintah membaca dan menghapus pesan pertama dari antrean.

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

    Karena isi pesan disimpan dikodekan base64, pesan harus dibaca sandi sebelum ditampilkan. Setelah Anda menjalankan az storage message get, pesan dihapus dari antrean. Jika hanya ada satu pesan dalam outqueue, Anda tidak akan mengambil pesan saat menjalankan perintah ini untuk kedua kalinya dan sebaliknya mendapatkan kesalahan.

Menyebarkan ulang proyek ke Azure

Sekarang setelah Anda memverifikasi secara lokal bahwa fungsi tersebut menulis pesan ke antrean Azure Storage, Anda dapat menyebarkan ulang proyek Anda untuk memperbarui titik akhir yang berjalan di Azure.

Di folder LocalFunctionsProj, gunakan perintah func azure functionapp publish untuk menyebarkan ulang proyek, ganti<APP_NAME> dengan nama aplikasi Anda.

func azure functionapp publish <APP_NAME>

Di folder proyek lokal, gunakan perintah Maven berikut ini untuk menerbitkan ulang proyek Anda:

mvn azure-functions:deploy

Memverifikasi di Azure

  1. Seperti pada mulai cepat sebelumnya, gunakan browser atau CURL untuk menguji fungsi yang telah disebarkan ulang.

    Salin Panggilan URL lengkap yang ditampilkan dalam output perintah terbitkan ke bilah alamat browser, menambahkan parameter kueri &name=Functions. Browser harus menampilkan output yang sama seperti saat Anda menjalankan fungsi secara lokal.

  2. Periksa lagi antrean Storage, seperti yang dijelaskan di bagian sebelumnya, untuk memverifikasi bahwa itu berisi pesan baru yang ditulis ke antrean.

Membersihkan sumber daya

Setelah selesai, gunakan perintah berikut untuk menghapus grup sumber daya dan semua sumber daya yang ada di dalamnya untuk menghindari timbulnya biaya lebih lanjut.

az group delete --name AzureFunctionsQuickstart-rg

Langkah berikutnya

Anda telah memperbarui fungsi pemicu HTTP Anda untuk menulis data ke antrean Storage. Sekarang Anda dapat mempelajari selengkapnya tentang mengembangkan Functions dari baris perintah menggunakan Core Tools dan Azure CLI: