Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Azure Functions Serisi #13 – Bindings

Merhaba,

Bu içeriğimizde geliştirdiğimiz Azure Function uygulamalarını diğer Azure servislerine bağlayarak kullanabilmemizi sağlayan Binding konusu üzerine detaylı izahat ve incelemede bulunacağız.

Azure Function Bindings Nedir?

Azure Function Bindings, Azure Function yapılanmasının en güçlü özelliğidir.

Azure Function Bindings, Azure Functionlar’ı diğer Azure servislerine bağlayarak kullanabilmemizi sağlayan bir özelliktir. İşlevsel açıdan spesifik bir örnek vermemiz gerekirse eğer; Http Trigger ile elde edilen datayı Azure Storage Table‘a yazdırmak, gelen dosyayı Azure Storage Blog‘a eklemek yahut asenkron işlenmesi gereken bir mesajı Azure Storage Queue‘da kuyruğa dahil etmek için bu servislerle function arasında bağlantıyı sağlayacak olan mekanizma binding yapılanmasıdır.

Normal şartlarda bir yazılım üzerinden Azure servislerine bağlantı sağlayabilmek için yapıyı inşa etmemiz gerekmektedir. Bu yazılım Azure Function olduğu zamanda süreç fark etmeyecek ve aynı işi tekrar sergilememiz gerekecektir. İşte burada binding özelliği sayesinde Azure Function’lar da ekstradan bağlantı için kodlamaya gerek kalmaksızın hazır nesneler aracılığıyla diğer servislere erişim rahatça gerçekleştirilebilecek ve iş mantığındaki ekstra yük ayıklanacağından dolayı kod ve iş maliyeti minimize edilmiş olacaktır.

Binding sayesinde ekstra kod yazmaksızın Azure içerisindeki birçok servise bağlantı gerçekleştirilebilmektedir.

Bindingler; Input Binding ve Output Binding olmak üzere ikiye ayrılırlar.

  • Input Binding
    Azure Function’ın ilgili servislere ekstradan kod yazmaksızın bağlanmasıdır. Function’ımız bu input binding üzerinden verileri okuyabilir, işleyebilir. Varsayılan binding türüdür.
  • Output Binding
    Azure Function’ın ilgili servislerden data’yı dışarıya göndermesi ve işletmesidir.

Binding Yapılanması(function.json)

Azure Function, binding mekanizmasını ‘function.json’ isimli dosya üzerinden yapılandırmaktadır. Binding, compile olabilen dillerde(Java, C#) attributes/annotations gibi yapılarla gerçekleştirilirken, compile olmayan dillerde(Node.JS) ise direkt olarak ‘function.json’ dosyası üzerinden gerçekleştirilmektedir. Lakin compile edilen dillerde her ne kadar attribute kullanılsada, esasında bu bir tanımlamadan ibarettir ve özünde ‘function.json’ dosyası oluşturulmuş olmakta ve kullanılmaktadır.

Örnek olması hasebiyle bir ‘function.json’ dosyasının nasıl oluşturulduğunu ve yapısal olarak ne olduğunu inceleyebilmek için Visual Studio’da geliştirdiğiniz Azure Function uygulamasını derleyiniz ve ardından aşağıdaki dizinine gidiniz;
...\{app_name}\{app_name}\bin\Debug\netcoreapp3.1\{function_name}
Dizini incelerseniz eğer {function_name} kısmının uygulama içerisinde tanımlanmış her bir function’a karşılık geldiğini anlayacaksınız. Misal; içerisinde ‘Function1’ ve ‘Function2’ isimli iki adet fonksiyon bulunan bir Azure Function uygulaması derlendikten sonra aşağıdaki çıktıyı verecektir.
Azure Functions Serisi #13 - Bindings
Bu klasörlerin her birinde bir ‘function.json’ dosyası mevcuttur.
Azure Functions Serisi #13 - Bindings
İşte bu dosya bizim binding yapılandırmasını barındıran dosyamızdır. Artık ilgili dosyanın içeriğine göz atabiliriz;

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-3.0.3",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "httpTrigger",
      "methods": [
        "get",
        "post"
      ],
      "authLevel": "function",
      "name": "req"
    }
  ],
  "disabled": false,
  "scriptFile": "../bin/ExampleAzureFunctions.dll",
  "entryPoint": "ExampleAzureFunctions.Function1.Run"
}
  • ‘configurationSource’
    Konfigürasyonun davranışsal olarak hangi kaynaktan olduğunu ifade eder. Yukarıdaki tanımda ‘attributes’ değerini taşıyarak, compile edilen bir dil kullanıldığını ve ilgili binding’in attribute aracılığı ile yapılandırıldığını ifade eder.
  • ‘type’
    Trigger’în türünü ifade eder.
  • ‘methods’
    İlgili function’ı hangi tür metotların tetikleyebileceğini ifade eder.
  • ‘authLevel’
    Function’ın hangi authentication level ile tanımlandığını ifade eder.
  • ‘name’
    İlgili Function’ı tetikleyecek olan trigger’ı yakalayacak request nesnesinin parametrik ismini ifade eder.

Bir binding işlemi için ‘function.json’ dosyasında en az nelerin yapılandırılması gerekmektedir?

  1. Yön(direction)
  2. Type(type) ve
  3. Name

bildirilmelidir. Yön; ilgili binding’in input mu output mu olduğunu ifade eder. Type; Hangi Azure servis’e(Queue, Table, Blob) binding yapılacağını bildirir. Name ise; request’i karşılayan parametrik nesnenin referansını temsil eder. Yukarıdaki örnek ‘function.json’ içeriğine göz atarsanız bu üç asli tanımın ‘direction’ hariç yapıldığını görmüş olacaksınız. Neden ‘direction’ tanımlaması yapılmamıştır? sorusuna karşılık –default olarak trigger’ların ‘input’ kabul edilmesinden dolayı– cevabını vermemiz yeterli olacaktır.

Binding, sadece Azure servisleri ile çalışmaktadır. Amazon, Google vs. gibi harici servislerle çalışabilmek için ilgili servise özgü hususi kodlamaların yapılması gerekmektedir.

Binding İşleminin Uygulanması

Bir Azure Function uygulaması üzerinden binding işleminin gerçekleştirilebilmesi için uygulamaya ‘Microsoft.Azure.WebJobs.Extensions.Storage‘ kütüphanesinin entegre edilmesi gerekmektedir.
Azure Functions Serisi #13 - Bindings

Table Output Binding

Şimdi aşağıda Table Output Binding’e özel bir örnek ele alalım;

    public static class Function1
    {
        const string routeName = "products";
        [FunctionName("Post")]
        async public static Task<IActionResult> Post(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = routeName)] HttpRequest req,
            ILogger log, [Table(tableName: "products", Connection = "StorageConnectionString")] CloudTable cloudTable)
        {
            string body = await new StreamReader(req.Body).ReadToEndAsync();
            Product product = JsonConvert.DeserializeObject<Product>(body);
            await cloudTable.CreateIfNotExistsAsync();
            TableOperation operation = TableOperation.Insert(product);
            TableResult tableResult = await cloudTable.ExecuteAsync(operation);

            return new OkObjectResult(tableResult.Result);
        }

        [FunctionName("Get")]
        async public static Task<IActionResult> Get(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = routeName)] HttpRequest req,
            ILogger log, [Table(tableName: "products", Connection = "StorageConnectionString")] CloudTable cloudTable)
        {
            return new OkObjectResult(cloudTable.CreateQuery<Product>().AsQueryable());
        }
    }

Yukarıdaki kod bloğunu incelerseniz eğer ‘Post’ ve ‘Get’ olmak üzere iki adet function oluşturulmuştur. Bu functionların ‘CloudTable’ isimli parametreleri ‘Table’ attribute’u aracılığıyla Table Storage servisine output binding ile bağlanmış bulunmaktadır. Ek olarak ‘Connection’ bilgisi ‘local.storage.json‘ dosyasındaki ‘StorageConnectionString’ alanında tutulmaktadır.

İlgili functionları Postman üzerinden test edelim…

POST GET
Azure Functions Serisi #13 - Bindings Azure Functions Serisi #13 - Bindings

Queue Output Binding

Şimdide bir Queue Output Binding’e örnek verelim;

    public static class Function1
    {
        const string routeName = "message";
        [FunctionName("Post")]
        async public static Task<IActionResult> Post(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = routeName)] HttpRequest req,
            ILogger log, [Queue(queueName: "mymessage", Connection = "StorageConnectionString")] CloudQueue cloudQueue)
        {
            string body = await new StreamReader(req.Body).ReadToEndAsync();
            await cloudQueue.CreateIfNotExistsAsync();
            CloudQueueMessage cloudQueueMessage = new CloudQueueMessage(body);
            await cloudQueue.AddMessageAsync(cloudQueueMessage);
            return new OkResult();
        }

        [FunctionName("Get")]
        async public static Task<IActionResult> Get(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = routeName)] HttpRequest req,
            ILogger log, [Queue(queueName: "mymessage", Connection = "StorageConnectionString")] CloudQueue cloudQueue)
        {
            return new OkObjectResult((await cloudQueue.GetMessageAsync()).AsString);
        }
    }
POST GET
Azure Functions Serisi #13 - Bindings Azure Functions Serisi #13 - Bindings

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

1 Cevap

  1. 18 Ağustos 2020

    […] Azure Functions Serisi #13 – Bindings […]

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir