Azure Functions ile Serverless Sipariş Uygulaması Geliştirme

Ufuk Aytaş
Devops Türkiye☁️ 🐧 🐳 ☸️
9 min readDec 30, 2020
Photo by Micheile Henderson on Unsplash

Bir önceki makalede Azure Functions konusunu incelemiştik. Alttaki linkten ulaşabilirsiniz.

Serverless yazı dizisi.

Not: Yeni makaleler geldikçe bu bölümü güncelleyeceğim.

Haydi başlayalım…

Sipariş Uygulaması

Merhaba, bu yazıda örnek bir Sipariş senaryosu oluşturarak bunu Azure Function, Storage Account Table ve Azure Service Bus kullanarak bir uygulama geliştireceğiz.

Yukarıda çizdiğim tabloya göre akış şu şekilde olacak.

  1. Kullanıcı E-Ticaret sisteminde bir sipariş oluşturur.
  2. Sipariş farklı kanallar aracılığı ile (Website, Mobile App, vs.) Order Function’a gelir.
  3. Sipariş bilgileri Storage Account’da bulunan Order Tablosuna yazılır.
  4. Sipariş detayları bildirim olarak gönderilebilmesi için mesaj Servis Bus’a iletilir.
  5. Azure Service Bus Topic’e gelen mesajı aboneler okuyarak (SMS Notification ve EMail Notification) sipariş işleminin sonucunu bildirim olarak gönderir.

Azure Portal’da (Resource) Kaynakların oluşturulması

Uygulamada kullanabilmek için Resource Group, Azure Function App, Storage Account ve Azure Service Bus’a ihtiyacımız var.
Sırası ile kaynakları ve gerekli yapılandırmaları oluşturalım.

Azure Resource Group

Uygulamalarımız için Azure’da farklı kaynaklar oluşturmamız gerekebilir. Bunların kolay bir şekilde yönetilmesi ve gruplandırılması için Azure Resource Group kullanılır.

Source: docs.microsoft.com

Resource Group, kaynakların yönetilmesi, maliyet yönetimi ve rol bazlı yetkilendirilme gibi özellikleri barındıran mantıksal bir ara katmandır.

Veritabanı, sanal ağlar, sanal makinalar, web uygulamaları oluştururken bizden resource group seçmemizi ister, eğer daha önceden oluşturmadıysak yeni bir tane oluşturarak bu kaynakların oluşturulmasına izin verir.

Ayrıca Dev, Test veya Production gibi ortamları oluştururken farklı Resource Group’lar oluşturabiliriz.

Eğer Resource Group’ları Azure Portal üzerinden oluşturuyorsanız her ortam için tek tek oluşturmanız gerekir ve değişiklik ihtiyacında tüm ortamlarda bunu uygulamanız biraz zordur. Bu yöntem yerine Template oluşturarak aynı template üzerinden farklı ortamlara bu kaynakları hızlıca oluşturabilirsiniz.

Alttaki linkten nasıl template oluşturacağını incelyebilirsiniz.

Her Cloud Vendor’unun kendi Resource Manager’ı var bu sayede şablonlar üreterek gerekli altyapı oluşturuluyor. Bunun yanında dilerseniz altyapıları kod yazarak üretmenizde mümkün. (Infrastructure-As-Code).

Biz ekip olarak ortamlar için Terraform kullanıyoruz. Sizde benzer IOC tool’ları kullanarak ortamlarınızı hızlıca ayağa kaldırabilirsiniz.

NOT: Bu konuyu farklı bir yazıda detaylandıracağım.

Şimdi Projemiz için yeni bir Resource Group oluşturalım.

Resource Group

Azure portal’a (http://portal.azure.com) giriş yaptıktan sonra arama çubuğuna “Resource Group” yazalım ve işaretli alanı seçerek Add diyelim ve yeni bir resource group oluşturalım.

Resource group adına “rg-ufuk-ordermanagement-test” diyorum ve Region olarak “West Europe” seçiyorum. Create diyerek Resource Group’umuzu oluşturalım.

Azure Function

Azure Functions, küçük kod parçalarını kolayca çalıştırmamızı sağlayan, uygulama geliştirmeyi hızlandırmak ve kolaylaştırmak için oluşturulmuş ve altyapı ihtiyaçlarının tamamen Azure tarafından yönetildiği serverless bir yaklaşımdır.

Detaylı bilgi için Azure Function Nedir? yazısını inceleyebilirsiniz.

Şimdi Azure Function’ımızı oluşturalım.

Arama çubuğuna “Function App” yazarak “Add” diyoruz ve gerekli bilgileri giriyoruz. Dilerseniz Resource Group’u seçerek içerisinde “Add” diyerek yeni bir kaynak (Resource) ekleyebilirsiniz.

Function App’imizin ismine “ordermanagementdemoapp” diyerek resource group’u seçiyorum. Runtime olarak .NET Core seçtim siz dilerseniz farklı bir dil’de seçebilirsiniz.

Bir sonraki adımda Hosting bilgilerini girmemiz gerekiyor. Azure Function’ların çalışması için bir Storage Account tanımlamamız gerekir. Proje için yeni bir Storage account oluşturdum ve ismine “ordermanagementsa” diyerek devam ediyorum. Operating System olarak “Linux” ve Servis Plan olarak “Consumption” seçerek devam ediyoruz.

Local ortamda geliştirme yapıyorken Storage Account için Storage Account Emulatör kullanacağım.

Monitoring adımında Application Insights eklemek isteyip istemediğinizi soracak. Bu aşamada Enabled seçerek devam ediyoruz.

Son olarak “Create” diyerek Azure Function App’imizi oluşturacağız.

Azure Storage Account Tablo oluşturma

Function App oluştururken “ordermanagementsa” adında bir storage account oluşturduk. Şimdi kullanmak üzere “Order” isminde bir tablo oluşturalım. Sol menüden Table’i seçiyoruz ve “Table” diyerek yeni bir tablo oluşturuyoruz.

Azure Table storage, ilişkisel olmayan NoSql verileri Cloud’da tutmaya yarayan bir hizmettir.

Azure Table Storage’da yeni bir tablo oluşturduğumuzda ‘Row Key’, ‘Partition Key’ ve ‘Timestamp’ alanları otomatik olarak gelir.

Azure Service Bus

Azure Service Bus, Azure platformunda çalışan ve uygulamaların ve hizmetlerin güvenilir bir şekilde birbiriyle haberleşebilmesi için geliştirilen kurumsal düzeyde bir mesajlaşma aracıdır.

Detaylı bilgi için Azure Service Bus nedir? Queue ve Topic kullanımı adlı yazıyı inceleyebilirsiniz.

Arama çubuğuna “Azure Service Bus” yazarak “Add” diyoruz. NameSpace adı için “ordermanagementdemoapp” ve Pricing Tier için Standart seçiyoruz. Eğer Basic katmanını seçerseniz sadece Queue kullanabiliyorsunuz. Projede Topic kullanacağımız için Standart seçerek devam ediyorum.

Create” diyerek resource’u oluşturuyoruz. Daha sonra uygulamada kullanabilmek için “NotificationTopic” isminde bir adet topic oluşturuyoruz.

Servis bus için connection String’e ihtiyacımız var. Bunun için Servis Bus’da Shared Access Policies’e girip “OrderManagement” isminde yeni bir policy oluşturalım. ConnectionString’i alıp local.setings.json içerisine “ServiceBusConnection” olarak ekleyelim.

Resource Group’umuzun son hali bu şekilde olacaktır.

Ortamlarımızı hazırladığımıza göre artık uygulamayı geliştireye başlayabiliriz.

Projenin Oluşturulması

Projeyi Visual Studio 2019 kullanarak oluşturacağız.

AzureServerlessOrderProcess” isminde bir solution oluşturuyoruz ve Add a New Project diyerek yeni bir Azure Function projesi seçiyoruz. Proje adı olarak “OrderProcess.Function” yazıp devam ediyoruz. Storage account için local ortamda genellikle Emulatör üzerinde çalışıyorum. Bu nedenle “Storage Emulator” seçerek devam ediyorum.

Data’ları Storage Table’da tutacağımız için Models klasörü altında “Order” isminde bir entity oluşturuyoruz ve “TableEntity” sınıfından türetiyoruz. TableEntity sınıfı ile Azure Storage Table’da default gelen ‘PartitionKey’, ‘RowKey’ ve ‘Timestamp’ propertyleri hazır olarak gelmektedir.

Şimdi adım adım uygulamamızı oluşturalım.

  1. Order Function : Siparişleri karşılayacak API için “OrderFunction” fonksiyonumuzu oluşturuyoruz. Bu fonksiyonda HttpTrigger ile Request’leri “OrderTable” a yazıp daha sonra Service Bus da bulunan “OrderNotificationTopic” ‘e mesaj olarak gönderecek.

Azure Functions’larda Input ve Output binding’lerden bahsetmiştik. HttpTrigger binding’i ile API için gelen “OrderRequest” modelindeki Request’i alıyoruz Azure Storage‘da oluşturduğumuz “Order” ismindeki tablo için Table binding oluşturuyoruz. Azure Servis Bus’a mesajımızı gönderebilmek için Service Bus binding oluşturarak notificationTopic’e mesajımızı gönderiyoruz.

Dto klasörü altında “OrderRequest.cs” modelimizi oluşturuyoruz ve Request için kullacağımız property’leri tanımlıyoruz.

2. SmsNotification Function: SMS Notification ve EMail Notification aynı Topic’i dinliyorlar. Order Notification için Topic’e mesaj gönderdiğimizde iki subscriber’a da mesaj iletiliyor. Servis Bus Topic’i dinlemek için “ServiceBusTrigger” kullanıyoruz. Mesaj subscriber’a düştüğü onda fonsiyonumuz otomatik olarak tetiklenecektir.

Sms göndermek için dilerseniz Twilio kullanabilirsiniz. Azure Function için binding’i mevcut. Alttaki linkten inceleyebilirsiniz.

3. EMailNotification Function : Aynı şekilde E-Mail Notification “notificationtopic”’i dinleyerek mesaj geldiğinde otomatik olarak tetiklenecektir.

E-Mail göndermek için dilerseniz SendGrid kullanabilirsiniz. Azure Function için binding’i mevcut. Alttaki linkten inceleyebilirsiniz.

Projemizi genel olarak tamamladık. local.settings.json dosyamızı incelersek Emulatör kullandığımız için “UseDevelopmentStorage=true” olarak setlenmiş olduğunu görebilirsiniz. ServiceBus için oluşturduğumuz ServiceBusConnection’ı buraya setliyoruz.

Şimdi projemizi Start diyerek çalıştıralım. Console’da OrderFunction’ın Http Trigger ile Notification için yazdığımız fonksiyonların ise Service Bus Trigger ile tetikleneceğini görüyoruz.

Postman ile OrderFunction’ımıza bir Post isteğinde bulunalım.

OrderFunction’a isteğimiz geldi. Request’de gönderdiğimiz bilgilere ulaştık.

Servis Bus’ı kontrol ettiğimizde Subscriber’lar için mesajın gönderilediğini göreceğiz.

Debug’ı devam ettirdiğimde “EmailNotificationFunction” Subscription’a gelen mesaj’dan dolayı tetikleniyor. Göndermiş olduğumuz mesajı burada okuyoruz.

Devam ettiğimizde SMSNotificationFunction’da aynı şekilde tetikleniyor.

Son olarak “Order” tablosunu kontrol ettiğimizde gönderdiğimiz data’nın burada oluştuğunu göreceğiz.

Console uygulamasını tekrar inceleyecek olursak işlemlerin sırası ile sorunsuz tamamlandığını göreceğiz.

Projemizin sorunsun çalıştığını gördüğümüze göre şimdi Cloud’a publish edebiliriz. Öncelikle Storage Account Connection String’i değiştirmemiz gerekiyor. Bunun için oluşturmuş olduğumuz Storage Account’a gidip Access Keys’den ConnectionString’i alalım ve local.settings.cs dosyasındaki AzureWebJobsStorage value’ya setleyelim.

Şimdi Projemizde sağ tıklayıp Publish diyelim ve çıkan ekranda Target olarak Azure’u seçelim ve “Next” diyelim. Azure Function App(Linux) seçelim ve yine “Next” diyelim. Function App için oluşturmuş olduğumuz ordermanagementfunctionapp’i seçiyoruz ve Finish diyoruz.

Son olarak Manage Azure App Service settings’e tıklayarak açılan ekranda “Insert Value from local” diyerek Remote AppSettings ile local settings bilgilerimizi eşitliyoruz. Daha sonra Publish diyerek projemizi Azure’a gönderiyoruz.

Projemiz deploy oldu şimdi test zamanı.

Postman’de API adresini function app url’imizle değiştirerek (http://ordermanagementdemoapp.azurewebsites.net/api/OrderFunction) Post atıyorum ve 401 Unauthorized hatası alıyorum.

Bunun sebebi oluşturduğumuz Order Function için AuthorizationLevel’i Function yapmış olmamız. Bu yetki seviyesinde Fonksiyonu çağırabilmemiz için FunctionKey’e ihtiyacımız var. Order Function’a giderek sol menüden Function Keys’e tıklıyoruz ve buradaki key’i alıyoruz.

API Url’in sonuca Code={FunctionKey} diyerek tekrar bir Post gönderelim.

Fonksiyonumuz başarılı bir şekilde tamamlanarak Response bilgisini döndü.

Ayrıca Notification için Email Notification’ı kontrol ettiğimde işlemin başarılı bir şekilde gerçekleştiğini görüyorum.

Azure’da oluşturduğumuz Storage Account Table’i kontrol ettiğimde gönderdiğimiz sipariş bilgisinin eklendiğini görüyorum.

Projeyi Azure’a publish ettikten sonra Test ortamındada beklediğimiz gibi çalıştığını gördük.

Sonuç

Bu yazıda Sipariş Uygulaması için gerekli olan Serverless bileşenlerinin oluşturulması ve bu bileşenlerin nasıl yapılandırılacağını adım adım gördük. Serverless yaklaşım altyapıdan tamamen soyutlanarak sadece business’a odaklanmamızı sağlamaktadır. Azure Functions’ın güçlü özelliklerinden Trigger ve Binding’ler ile farklı servisler arasında kolayca entegre edilmesi ve hazır nesnelerle veriler üzerinden kolayca geliştirme yapmamıza imkan tanımaktadır.

Bir sonraki makalede görüşmek üzere…

Sorularınız için lütfen yorum yapmaktan ve bana ulaşmaktan çekinmeyin.

Twitter: https://twitter.com/ufukaytas
Linkedin: https://www.linkedin.com/in/ufukaytass/
Github: https://github.com/ufukaytas/

--

--

Ufuk Aytaş
Devops Türkiye☁️ 🐧 🐳 ☸️

Software Architect & Developer @CorendonDutchAirlines, Husband, Dad, Fishing, Coffee addict :) #Serverless #Cloud, #Azure, #Dotnet