<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Azure Functions - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Azure Functions - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 22:38:26 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/azure-functions/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Create Serverless Logic with Azure Functions ]]>
                </title>
                <description>
                    <![CDATA[ What is Serverless Computing? Serverless computing is a cloud computing model where backend services are provided on a pay-as-you-use basis.  In this model, developers get to create and run development code without having to manage or provision serve... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-serverless-logic-with-azure-functions/</link>
                <guid isPermaLink="false">66ba2dccc346e93df556aff9</guid>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Azure Functions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Salim Oyinlola ]]>
                </dc:creator>
                <pubDate>Mon, 26 Sep 2022 22:35:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/pexels-sagui-andrea-618833.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-what-is-serverless-computing"><strong>What is Serverless Computing?</strong></h2>
<p>Serverless computing is a cloud computing model where backend services are provided on a pay-as-you-use basis. </p>
<p>In this model, developers get to create and run development code without having to manage or provision servers. As such, they get to focus solely on writing the business logic (or front-end development) code instead. </p>
<p>Microsoft Azure provides a wide range of options for designing this kind of architecture. However, the most frequently used methods are Azure Logic Apps and Azure Functions which will be the main focus of this article. </p>
<h2 id="heading-what-are-azure-functions"><strong>What are Azure Functions?</strong></h2>
<p>Azure Functions is the serverless computing model on Microsoft Azure platform for creating serverless applications. It enables developers to host their business logics without the need for infrastructure. </p>
<p>The code for Azure functions can be written in a wide range of programming languages including C#, JavaScript, and Python, amongst others. Like other cloud services, it operates on a pay-per-use basis, where you only pay for the resources you consume. </p>
<p>By the end of this tutorial, you will be able to:</p>
<ul>
<li>Create an Azure function app in the Azure portal.</li>
<li>Exercise a function using triggers.</li>
<li>Monitor and test your Azure function from the Azure portal.</li>
</ul>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<p>You will need a valid and active Microsoft Azure account to follow along with this tutorial. You can use either:</p>
<ul>
<li><a target="_blank" href="https://azure.microsoft.com/en-us/free/">Free Azure Trial</a>: With this option, you will start with $200 Azure credit and will have 30 days to use it, in addition to free services.</li>
<li><a target="_blank" href="https://azure.microsoft.com/en-us/free/students/">Azure for Students</a>: This offer is available for students only. With this option, you will start with $100 Azure credit with no credit card required and access to popular services for free whilst you have your credit.</li>
</ul>
<h2 id="heading-step-1-create-your-azure-function-app"><strong>Step 1 – Create your Azure Function App</strong></h2>
<p>To establish a serverless computing resource for your business logic using Azure Functions, it is essential to create an Azure Function application. Having created a valid and active Microsoft Azure account, navigate to the <a target="_blank" href="https://portal.azure.com/">portal</a>. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-128.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ul>
<li>Select <code>Create a resource</code> </li>
<li>Select the <code>Create</code> button underneath the <code>Function App</code> pane. </li>
<li>On clicking the button, a page where you enter the details of your project appears as shown below. </li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-129.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-130.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-131.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Enter the configuration details for this tutorial under the <code>Basics</code> tab before clicking the <code>Review + create</code> button</p>
<ul>
<li>Enter the <code>Subscription</code> available on your account. Note that your subscription might not be <code>Visual Studio Enterprise Subscription</code> as shown in mine. </li>
<li>For the <code>Resource group</code>, if you have created one before, you could use it. However, if you have not created one or are not familiar with Azure resource group, create a new one by using the <code>Create new</code> button. </li>
</ul>
<p>At its core, a resource group is used to group similar Azure services on your Azure subscription together to make managing them easier. </p>
<ul>
<li>For the <code>Function App name</code> option, enter a globally unique app name. It is important to note that this name is will become part of the base URL for your service. </li>
<li>For the <code>Publish</code> option, select <code>Code</code>. </li>
<li>Choose <code>Node.js</code> for the <code>Runtime Slack</code> option since this tutorial's function examples were implemented using that language.</li>
<li>Leave the <code>Version</code> option as default.</li>
<li>Select the region that is geographically nearest to you when filling out the <code>Region</code> choice. A region is a collection of physical server data centers. Given that my base of operations is in Lagos, Nigeria, I chose <code>South Africa North</code>.</li>
<li>For the <code>Operating System</code>, select one that conforms with your selection of runtime.</li>
<li>For the <code>Plan</code> option, select <code>Consumption (Serverless)</code>. The plan you choose will determine how your app scales and what features are enabled.  </li>
<li>At this point, you can then click the <code>Review + create</code> button.</li>
</ul>
<p>The validation and deployment process usually takes up to three minutes. When the validation and deployment processes are both completed for the Azure Function set up, you can then verify that your Azure function app is running.</p>
<h2 id="heading-step-2-verify-that-your-azure-function-app-is-running"><strong>Step 2 – Verify that your Azure Function App is Running</strong></h2>
<p>Once the deployment process is done, select <code>Go to resource</code>. Your function's App pane will now appear. To open it in a browser, select the <code>URL</code> link in the <code>Essentials</code> section. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-132.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>With the message above, you will see a standard Azure functions web app page appear: <em>Your Function 4.0 app is up and running.</em> </p>
<h2 id="heading-step-3-run-your-code-on-demand-with-azure-functions"><strong>Step 3 – Run your Code On-Demand with Azure Functions</strong></h2>
<p>With the function app created, the next step is to build and configure the function. To do this, you have to understand what Triggers and Bindings are. </p>
<blockquote>
<p>Triggers cause a function to run. A trigger defines how a function is invoked and a function must have exactly one trigger. Triggers have associated data, which is often provided as the payload of the function. Binding to a function is a way of declaratively connecting another resource to the function; bindings may be connected as <em>input bindings</em>, <em>output bindings</em>, or both. Data from bindings is provided to the function as parameters. – <a target="_blank" href="https://learn.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings?tabs=csharp">Microsoft Learn Documentation</a></p>
</blockquote>
<p>In general, Azure Functions run in response to an event. This event is known as a <strong>Trigger</strong> and <strong>Bindings</strong> are used to connect resources to a function. The typical triggers on Azure range from a blob storage that runs a function when a blob is created or updated to a timer that runs a function on a schedule.</p>
<p>To run your code on Azure Functions, you need to first create your function to run your code within the function app using the template. </p>
<p>To do this, click the <code>Function</code> tag on the menu bar on the left of your functions app's home page. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-134.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ul>
<li>Click the <code>+ Create</code> button to create the function. </li>
<li>Select the <code>Azure Queue Storage trigger</code> template. This trigger runs the functions app when it detects that a message has been added to an Azure storage queue. </li>
<li>Leave everything else as its default value. </li>
<li>Click the <code>Create</code> button to create the function. </li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-135.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Given that the function was created with a template, several other files will be created automatically. These files comprises of a source code and a configuration file. </p>
<ul>
<li>Click on the <code>Code + Test</code> button on the left pane and open the <code>function.json</code> file by selecting it from the dropdown. </li>
<li>Replace the block of code it shows with the one below. </li>
</ul>
<pre><code class="lang-python">{
  <span class="hljs-string">"bindings"</span>: [
    {
      <span class="hljs-string">"name"</span>: <span class="hljs-string">"order"</span>,
      <span class="hljs-string">"type"</span>: <span class="hljs-string">"queueTrigger"</span>,
      <span class="hljs-string">"direction"</span>: <span class="hljs-string">"in"</span>,
      <span class="hljs-string">"queueName"</span>: <span class="hljs-string">"myqueue-items"</span>,
      <span class="hljs-string">"connection"</span>: <span class="hljs-string">"MY_STORAGE_ACCT_APP_SETTING"</span>
    },
    {
      <span class="hljs-string">"name"</span>: <span class="hljs-string">"$return"</span>,
      <span class="hljs-string">"type"</span>: <span class="hljs-string">"table"</span>,
      <span class="hljs-string">"direction"</span>: <span class="hljs-string">"out"</span>,
      <span class="hljs-string">"tableName"</span>: <span class="hljs-string">"outTable"</span>,
      <span class="hljs-string">"connection"</span>: <span class="hljs-string">"MY_TABLE_STORAGE_ACCT_APP_SETTING"</span>
    }
  ]
}
</code></pre>
<p>This block of code sets the trigger for the function as <strong>when a message is added to the queue named <code>myqueue-items</code>.</strong> Furthermore, it sends the return value to the <code>outTable</code>. </p>
<ul>
<li>Save and <em>Test/Run</em> the function whilst leaving the testing details as their default values and run the function app. </li>
<li>You will see the output shown below.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-136.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The fact that the outcome automatically displays on the <strong>Output tab</strong> suggests that the function app functions well. Because there isn't any business logic applied to the function, the graphic above is blank.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this tutorial, you have seen that serverless computing is a great option for hosting business logic code in the cloud. You have seen that with serverless offers such as Azure Functions, you can write your business logic in the language of your choice.</p>
<p>Also, it is important to note that not only does the use of serverless computing solutions avoid the over-allocation of infrastructure (because they can be created and destroyed on demand), but they are also event driven. Event driven in the sense that they run only in response to an event (called a 'trigger'), such as a message being added to a queue, or receiving an HTTP request.</p>
<p>Finally, I share my writings on <a target="_blank" href="https://twitter.com/SalimOyinlola">Twitter</a> if you enjoyed this article and want to see more.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Convert HTML to PDF with Azure Functions and wkhtmltopdf ]]>
                </title>
                <description>
                    <![CDATA[ By Arjav Dave In this article, we are going to use Azure Functions and the wkhtmltopdf tool to generate a PDF file from an HTML file.  You might want to create a PDF file for a great many reasons, such as generating invoices for sales, medical report... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/convert-html-to-pdf-with-azure-functions-and-wkhtmltopdf/</link>
                <guid isPermaLink="false">66d84de4175544516f70c43f</guid>
                
                    <category>
                        <![CDATA[ Azure Functions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ pdf ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 20 Apr 2021 16:02:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/04/html-to-pdf.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Arjav Dave</p>
<p>In this article, we are going to use Azure Functions and the <a target="_blank" href="https://wkhtmltopdf.org/">wkhtmltopdf</a> tool to generate a PDF file from an HTML file. </p>
<p>You might want to create a PDF file for a great many reasons, such as generating invoices for sales, medical reports for your patients, insurance forms for your clients, and so on. And there are a few ways to do this.</p>
<p>Firstly, you can use <a target="_blank" href="https://www.adobe.com/in/acrobat/online/sign-pdf.html">Adobe</a>'s fill and sign tool to fill out forms. But this mostly requires a human interaction and so it’s not scalable or convenient.</p>
<p>The second option is that you directly create a PDF file. Based on the platform you are working on you will have tools to do this. If it’s a very simple PDF you can take this approach.</p>
<p>This brings us to our final and most convenient option, <a target="_blank" href="https://wkhtmltopdf.org/">wkhtmltopdf</a>. This is a really great tool that lets you convert your HTML to PDF. Since it is free, open source, and can be compiled for almost all platforms, it is our best choice.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li>VS Code editor installed</li>
<li>An account on <a target="_blank" href="https://portal.azure.com/">Azure Portal</a></li>
<li>Linux Basic (B1) App Service Plan. If you already have a Windows Basic (B1) App Service Plan you can use that.</li>
<li>Azure Storage Account.</li>
</ul>
<h2 id="heading-how-to-use-azure-functions">How to Use Azure Functions</h2>
<p>Since converting HTML to a PDF is a time consuming task, we shouldn’t run it on our main web server. Otherwise it may start blocking other important requests. Azure Functions are the best way to delegate such tasks.</p>
<p>In order to create a function you will first need to install Azure Functions on your machine. Based on your OS install the <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=macos%2Ccsharp%2Cbash#install-the-azure-functions-core-tools">Azure Functions Core Tools</a>. </p>
<p>Once installed open your command line tool to fire the below command. <code>html2pdf</code> is the project’s name here, but you can replace it with any name.</p>
<p><code>func init html2pdf</code></p>
<p>When you execute the command it will ask for a worker runtime. Here select option 1, dotnet since it's a Microsoft’s product and provides great support for dotnet. </p>
<p>This will generate a folder name <code>html2pdf</code> in your current directory. Since Visual Studio Code allows to directly publish to Azure Functions, we will use it to code and deploy.</p>
<p>After you open your project in VS Code, create a file named <code>Html2Pdf.cs</code>. Azure Functions provides a wide variety of <a target="_blank" href="https://www.serverless360.com/blog/azure-functions-triggers-and-bindings">triggers</a> to execute the function. For now we will start with the HTTP trigger, that is the function can be called directly via the HTTP protocol. </p>
<p>In our newly created file, paste the below content:</p>
<pre><code>using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace Html2Pdf
{
    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Html2Pdf</span>
    </span>{
        <span class="hljs-comment">// The name of the function</span>
        [FunctionName(<span class="hljs-string">"Html2Pdf"</span>)]

        <span class="hljs-comment">// The first arugment tells that the functions can be triggerd by a POST HTTP request. </span>
        <span class="hljs-comment">// The second argument is mainly used for logging information, warnings or errors</span>
        public <span class="hljs-keyword">void</span> Run([HttpTrigger(AuthorizationLevel.Function, <span class="hljs-string">"POST"</span>)] Html2PdfRequest Request, ILogger Log)
        {
        }
    }
}
</code></pre><p>We have created the skeleton and now we will fill in the details. As you might have noticed the type of request variable is <code>Html2PdfRequest</code>. So let’s create a model <code>Html2PdfRequest.cs</code> class as below:</p>
<pre><code>namespace Html2Pdf
{
    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Html2PdfRequest</span>
    </span>{
        <span class="hljs-comment">// The HTML content that needs to be converted.</span>
        public string HtmlContent { get; set; }

        <span class="hljs-comment">// The name of the PDF file to be generated</span>
        public string PDFFileName { get; set; }
    }
}
</code></pre><h2 id="heading-how-to-add-dinktopdf-to-your-project">How to Add DinkToPdf to Your Project</h2>
<p>In order to invoke wkhtmltopdf from our managed code, we use a technology called P/Invoke.</p>
<p>In short <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke">P/Invoke</a> allows us to access structs, callbacks, and functions in unmanaged libraries. There is a nice P/Invoke wrapper named <a target="_blank" href="https://github.com/rdvojmoc/DinkToPdf">DinkToPdf</a> that allows us to abstract away the technicalities.</p>
<p>You can add DinkToPdf to your project via <a target="_blank" href="https://www.nuget.org/packages/DinkToPdf/">nuget</a>. Simply run the command from your root folder.</p>
<pre><code>dotnet add package DinkToPdf --version <span class="hljs-number">1.0</span><span class="hljs-number">.8</span>
</code></pre><p>Time to add some code at the top of our class <code>Html2Pdf</code>:</p>
<pre><code><span class="hljs-comment">// Read more about converter on: https://github.com/rdvojmoc/DinkToPdf</span>
<span class="hljs-comment">// For our purposes we are going to use SynchronizedConverter</span>
IPdfConverter pdfConverter = <span class="hljs-keyword">new</span> SynchronizedConverter(<span class="hljs-keyword">new</span> PdfTools());

<span class="hljs-comment">// A function to convert html content to pdf based on the configuration passed as arguments</span>
<span class="hljs-comment">// Arguments:</span>
<span class="hljs-comment">// HtmlContent: the html content to be converted</span>
<span class="hljs-comment">// Width: the width of the pdf to be created. e.g. "8.5in", "21.59cm" etc.</span>
<span class="hljs-comment">// Height: the height of the pdf to be created. e.g. "11in", "27.94cm" etc.</span>
<span class="hljs-comment">// Margins: the margis around the content</span>
<span class="hljs-comment">// DPI: The dpi is very important when you want to print the pdf.</span>
<span class="hljs-comment">// Returns a byte array of the pdf which can be stored as a file</span>
private byte[] BuildPdf(string HtmlContent, string Width, string Height, MarginSettings Margins, int? DPI = <span class="hljs-number">180</span>)
{
  <span class="hljs-comment">// Call the Convert method of SynchronizedConverter "pdfConverter"</span>
  <span class="hljs-keyword">return</span> pdfConverter.Convert(<span class="hljs-keyword">new</span> HtmlToPdfDocument()
            {
                <span class="hljs-comment">// Set the html content</span>
                Objects =
                {
                    <span class="hljs-keyword">new</span> ObjectSettings
                    {
                        HtmlContent = HtmlContent
                    }
                },
                <span class="hljs-comment">// Set the configurations</span>
                GlobalSettings = <span class="hljs-keyword">new</span> GlobalSettings
                {
                    <span class="hljs-comment">// PaperKind.A4 can also be used instead PechkinPaperSize</span>
                    PaperSize = <span class="hljs-keyword">new</span> PechkinPaperSize(Width, Height),
                    DPI = DPI,
                    Margins = Margins
                }
            });
}
</code></pre><p>I have added inline comments so that the code is self-explanatory. If you have any questions you can ask me on Twitter. Let’s call the above created function from our <code>Run</code> method.</p>
<pre><code><span class="hljs-comment">// PDFByteArray is a byte array of pdf generated from the HtmlContent </span>
<span class="hljs-keyword">var</span> PDFByteArray = BuildPdf(Request.HtmlContent, <span class="hljs-string">"8.5in"</span>, <span class="hljs-string">"11in"</span>, <span class="hljs-keyword">new</span> MarginSettings(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>,<span class="hljs-number">0</span>));
</code></pre><p>Once the byte array is generated, let’s store that as a blob in Azure Storage. Before you upload the blob, make sure you create a container. Once you do that, add the below code after <code>PDFByteArray</code>.</p>
<pre><code><span class="hljs-comment">// The connection string of the Storage Account to which our PDF file will be uploaded</span>
<span class="hljs-comment">// Make sure to replace with your connection string.</span>
<span class="hljs-keyword">var</span> StorageConnectionString = <span class="hljs-string">"DefaultEndpointsProtocol=https;AccountName=&lt;YOUR ACCOUNT NAME&gt;;AccountKey=&lt;YOUR ACCOUNT KEY&gt;;EndpointSuffix=core.windows.net"</span>;

<span class="hljs-comment">// Generate an instance of CloudStorageAccount by parsing the connection string</span>
<span class="hljs-keyword">var</span> StorageAccount = CloudStorageAccount.Parse(StorageConnectionString);

<span class="hljs-comment">// Create an instance of CloudBlobClient to connect to our storage account</span>
CloudBlobClient BlobClient = StorageAccount.CreateCloudBlobClient();

<span class="hljs-comment">// Get the instance of CloudBlobContainer which points to a container name "pdf"</span>
<span class="hljs-comment">// Replace your own container name</span>
CloudBlobContainer BlobContainer = BlobClient.GetContainerReference(<span class="hljs-string">"pdf"</span>);

<span class="hljs-comment">// Get the instance of the CloudBlockBlob to which the PDFByteArray will be uploaded</span>
CloudBlockBlob Blob = BlobContainer.GetBlockBlobReference(Request.PDFFileName);

<span class="hljs-comment">// Upload the pdf blob</span>
<span class="hljs-keyword">await</span> Blob.UploadFromByteArrayAsync(PDFByteArray, <span class="hljs-number">0</span>, PDFByteArray.Length);
</code></pre><p>You will see some errors and warnings after you add this code. To fix those, first add the missing import statements. Second, change the return type from <code>void</code> to <code>async Task</code> for the <code>Run</code> function. Here is what the final <code>Html2Pdf.cs</code> file will look like:</p>
<pre><code>using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using DinkToPdf;
using IPdfConverter = DinkToPdf.Contracts.IConverter;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System.Threading.Tasks;

namespace Html2Pdf
{
    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Html2Pdf</span>
    </span>{
        <span class="hljs-comment">// Read more about converter on: https://github.com/rdvojmoc/DinkToPdf</span>
        <span class="hljs-comment">// For our purposes we are going to use SynchronizedConverter</span>
        IPdfConverter pdfConverter = <span class="hljs-keyword">new</span> SynchronizedConverter(<span class="hljs-keyword">new</span> PdfTools());

        <span class="hljs-comment">// A function to convert html content to pdf based on the configuration passed as arguments</span>
        <span class="hljs-comment">// Arguments:</span>
        <span class="hljs-comment">// HtmlContent: the html content to be converted</span>
        <span class="hljs-comment">// Width: the width of the pdf to be created. e.g. "8.5in", "21.59cm" etc.</span>
        <span class="hljs-comment">// Height: the height of the pdf to be created. e.g. "11in", "27.94cm" etc.</span>
        <span class="hljs-comment">// Margins: the margis around the content</span>
        <span class="hljs-comment">// DPI: The dpi is very important when you want to print the pdf.</span>
        <span class="hljs-comment">// Returns a byte array of the pdf which can be stored as a file</span>
        private byte[] BuildPdf(string HtmlContent, string Width, string Height, MarginSettings Margins, int? DPI = <span class="hljs-number">180</span>)
        {
            <span class="hljs-comment">// Call the Convert method of SynchronizedConverter "pdfConverter"</span>
            <span class="hljs-keyword">return</span> pdfConverter.Convert(<span class="hljs-keyword">new</span> HtmlToPdfDocument()
            {
                <span class="hljs-comment">// Set the html content</span>
                Objects =
                {
                    <span class="hljs-keyword">new</span> ObjectSettings
                    {
                        HtmlContent = HtmlContent
                    }
                },
                <span class="hljs-comment">// Set the configurations</span>
                GlobalSettings = <span class="hljs-keyword">new</span> GlobalSettings
                {
                    <span class="hljs-comment">// PaperKind.A4 can also be used instead of width &amp; height</span>
                    PaperSize = <span class="hljs-keyword">new</span> PechkinPaperSize(Width, Height),
                    DPI = DPI,
                    Margins = Margins
                }
            });
        }

        <span class="hljs-comment">// The name of the function</span>
        [FunctionName(<span class="hljs-string">"Html2Pdf"</span>)]

        <span class="hljs-comment">// The first arugment tells that the functions can be triggerd by a POST HTTP request. </span>
        <span class="hljs-comment">// The second argument is mainly used for logging information, warnings or errors</span>
        public <span class="hljs-keyword">async</span> Task Run([HttpTrigger(AuthorizationLevel.Function, <span class="hljs-string">"POST"</span>)] Html2PdfRequest Request, ILogger Log)
        {
            <span class="hljs-comment">// PDFByteArray is a byte array of pdf generated from the HtmlContent </span>
            <span class="hljs-keyword">var</span> PDFByteArray = BuildPdf(Request.HtmlContent, <span class="hljs-string">"8.5in"</span>, <span class="hljs-string">"11in"</span>, <span class="hljs-keyword">new</span> MarginSettings(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>));

            <span class="hljs-comment">// The connection string of the Storage Account to which our PDF file will be uploaded</span>
            <span class="hljs-keyword">var</span> StorageConnectionString = <span class="hljs-string">"DefaultEndpointsProtocol=https;AccountName=&lt;YOUR ACCOUNT NAME&gt;;AccountKey=&lt;YOUR ACCOUNT KEY&gt;;EndpointSuffix=core.windows.net"</span>;

            <span class="hljs-comment">// Generate an instance of CloudStorageAccount by parsing the connection string</span>
            <span class="hljs-keyword">var</span> StorageAccount = CloudStorageAccount.Parse(StorageConnectionString);

            <span class="hljs-comment">// Create an instance of CloudBlobClient to connect to our storage account</span>
            CloudBlobClient BlobClient = StorageAccount.CreateCloudBlobClient();

            <span class="hljs-comment">// Get the instance of CloudBlobContainer which points to a container name "pdf"</span>
            <span class="hljs-comment">// Replace your own container name</span>
            CloudBlobContainer BlobContainer = BlobClient.GetContainerReference(<span class="hljs-string">"pdf"</span>);

            <span class="hljs-comment">// Get the instance of the CloudBlockBlob to which the PDFByteArray will be uploaded</span>
            CloudBlockBlob Blob = BlobContainer.GetBlockBlobReference(Request.PDFFileName);

            <span class="hljs-comment">// Upload the pdf blob</span>
            <span class="hljs-keyword">await</span> Blob.UploadFromByteArrayAsync(PDFByteArray, <span class="hljs-number">0</span>, PDFByteArray.Length);
        }
    }
}
</code></pre><p>This concludes the coding part of this tutorial!</p>
<h2 id="heading-how-to-add-wkhtmltopdf-to-your-project">How to Add wkhtmltopdf to Your Project</h2>
<p>We will still need to add the wkhtmltopdf library in our project. There are a few caveats when you're selecting a particular Azure App Plan. Based on the plan, we will have to get the wkhtmltopdf library. </p>
<p>For our purposes we have selected the Linux Basic (B1) App Service Plan since Windows Basic (B1) App Service Plan is five times more expensive.</p>
<p>At the time of writing this blog, the Azure App Service Plan was using Debian 10 with amd64 architecture. Luckily for us, DinkToPdf provides <a target="_blank" href="https://github.com/rdvojmoc/DinkToPdf/tree/master/v0.12.4/64%20bit">precompiled libraries</a> for Linux, Windows, and MacOS. </p>
<p>Download the .so library for Linux and put it in your project’s root folder. I am working on MacOS so I downloaded libwkhtmltox.dylib as well. </p>
<p>If you are using Windows or if you have hosted the Azure Functions on the Windows App Service Plan you must download the libwkhtmltox.dll. Here is how our project structure will look now:</p>
<p><img src="https://i2.wp.com/arjavdave.com/wp-content/uploads/2021/03/Screenshot-2021-03-21-at-4.41.20-PM.png?resize=676%2C546&amp;ssl=1" alt="Image" width="600" height="400" loading="lazy">
<em>Project Structure</em></p>
<p>When we create a build we need to include the .so library. In order to do that, open your csproj file and add the below content to the ItemGroup.</p>
<pre><code>&lt;None Update=<span class="hljs-string">"./libwkhtmltox.so"</span>&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">CopyToOutputDirectory</span>&gt;</span>PreserveNewest<span class="hljs-tag">&lt;/<span class="hljs-name">CopyToOutputDirectory</span>&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">CopyToPublishDirectory</span>&gt;</span>Always<span class="hljs-tag">&lt;/<span class="hljs-name">CopyToPublishDirectory</span>&gt;</span></span>
&lt;/None&gt;
</code></pre><p>Here is the whole csproj file:</p>
<pre><code>&lt;Project Sdk=<span class="hljs-string">"Microsoft.NET.Sdk"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">TargetFramework</span>&gt;</span>netcoreapp3.1<span class="hljs-tag">&lt;/<span class="hljs-name">TargetFramework</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">AzureFunctionsVersion</span>&gt;</span>v3<span class="hljs-tag">&lt;/<span class="hljs-name">AzureFunctionsVersion</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"DinkToPdf"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"1.0.8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.NET.Sdk.Functions"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"3.0.11"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">None</span> <span class="hljs-attr">Update</span>=<span class="hljs-string">"host.json"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">CopyToOutputDirectory</span>&gt;</span>PreserveNewest<span class="hljs-tag">&lt;/<span class="hljs-name">CopyToOutputDirectory</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">None</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">None</span> <span class="hljs-attr">Update</span>=<span class="hljs-string">"local.settings.json"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">CopyToOutputDirectory</span>&gt;</span>PreserveNewest<span class="hljs-tag">&lt;/<span class="hljs-name">CopyToOutputDirectory</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">CopyToPublishDirectory</span>&gt;</span>Never<span class="hljs-tag">&lt;/<span class="hljs-name">CopyToPublishDirectory</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">None</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">None</span> <span class="hljs-attr">Update</span>=<span class="hljs-string">"./libwkhtmltox.so"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">CopyToOutputDirectory</span>&gt;</span>PreserveNewest<span class="hljs-tag">&lt;/<span class="hljs-name">CopyToOutputDirectory</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">CopyToPublishDirectory</span>&gt;</span>Always<span class="hljs-tag">&lt;/<span class="hljs-name">CopyToPublishDirectory</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">None</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span></span>
&lt;/Project&gt;
</code></pre><h2 id="heading-how-to-create-the-azure-functions-app">How to Create the Azure Functions App</h2>
<p>Before we deploy to Azure Functions we will have to create it in Azure Portal. You can go to Azure Portal and start creating the <em>Azure Functions</em> resource. Follow the below screenshots for clarity.</p>
<p><img src="https://i2.wp.com/arjavdave.com/wp-content/uploads/2021/03/Untitled-1.jpg?resize=750%2C724&amp;ssl=1" alt="Image" width="600" height="400" loading="lazy">
<em>Instance Details</em></p>
<p>In the below screenshot, make sure to select or create at least the <em>Basic</em> Plan here. Secondly, in the Operating System select <em>Linux</em>.</p>
<p><img src="https://i2.wp.com/arjavdave.com/wp-content/uploads/2021/03/Screenshot-2021-03-22-at-10.30.48-AM.png?resize=750%2C784&amp;ssl=1" alt="Image" width="600" height="400" loading="lazy">
<em>Plan Details</em></p>
<p>It’s good to have <em>Application Insights</em> since you will be able to see logs and monitor functions. Besides, it hardly costs anything. As shown in the screenshot below, select <em>Yes</em> if you want to enable it.</p>
<p><img src="https://i1.wp.com/arjavdave.com/wp-content/uploads/2021/03/Screenshot-2021-03-22-at-10.31.11-AM.png?resize=750%2C798&amp;ssl=1" alt="Image" width="600" height="400" loading="lazy">
<em>Application Insights</em></p>
<p>Select Next: Tags and again click Next and click <em>Create</em> to create your resource. It might take a few minutes to create the <em>Azure Functions</em> resource.</p>
<h2 id="heading-how-to-deploy-to-azure-functions">How to Deploy to Azure Functions</h2>
<p>Once created, we will deploy our code directly to Azure Functions via VS Code. For that you will have to go to the extensions and install the <em>Azure Functions</em> extension. With its help we will be able to login and manage Azure Functions.</p>
<p><img src="https://i1.wp.com/arjavdave.com/wp-content/uploads/2021/03/Screenshot-2021-03-22-at-10.03.00-AM.png?resize=750%2C433&amp;ssl=1" alt="Image" width="600" height="400" loading="lazy">
<em>Azure Functions in Marketplace</em></p>
<p>Once installed you will see the Azure icon on the side bar. When you click it, it will open a panel with an option to <em>Sign In to Azure</em>.</p>
<p><img src="https://i1.wp.com/arjavdave.com/wp-content/uploads/2021/03/Screenshot-2021-03-22-at-10.19.08-AM.png?resize=750%2C846&amp;ssl=1" alt="Image" width="600" height="400" loading="lazy">
<em>Azure Functions Extension</em></p>
<p>Select <em>Sign in to Azure</em> which will open a browser where you can login with your account. Once logged in, you can go back to VS Code and see the list of Azure Functions in your side panel.</p>
<p><img src="https://i0.wp.com/arjavdave.com/wp-content/uploads/2021/03/Screenshot-2021-03-22-at-10.43.07-AM.png?resize=670%2C656&amp;ssl=1" alt="Image" width="600" height="400" loading="lazy">
<em>List of Azure Functions</em></p>
<p>For me there are four function apps. Since you might have created just one it will show one. Now it's time to deploy the app.</p>
<p>Press <em>F1</em> to open a menu with a list of actions. Select <em>Azure Functions: Deploy to Function App…</em> which will open a list of Azure Functions to which you can deploy. </p>
<p>Select our newly created Azure Funtions App. This will ask for a confirmation pop-up, so go ahead and deploy it. It will take a few minutes to deploy your App.</p>
<h2 id="heading-how-to-configure-wkhtmltopdf">How to Configure wkhtmltopdf</h2>
<p>Once you have deployed to Azure Functions there is still one last thing to do. We will need to add <code>libwkhtmltox.so</code> to a proper location on our Azure Functions App. </p>
<p>Login to Azure portal and navigate to our Azure Functions App. On the side panel search for SSH and click the <em>Go</em> button.</p>
<p><img src="https://i2.wp.com/arjavdave.com/wp-content/uploads/2021/03/Screenshot-2021-03-22-at-12.14.03-PM.png?resize=750%2C219&amp;ssl=1" alt="Image" width="600" height="400" loading="lazy">
<em>Search SSH for Azure Functions</em></p>
<p>This will open a SSH console in new tab. Our site is located at /home/site/wwwroot. So navigate to that folder by typing in the below command:</p>
<pre><code>cd /home/site/wwwroot/bin
</code></pre><p>When you execute the <code>ls</code> command to view the contents of the file you won’t see the <code>libwkhtmltox.so</code> file. It is actually located at /home/site/wwwroot.</p>
<p>That is not the correct position. We need to copy it into the bin folder. To do that, execute the below command:</p>
<pre><code>cp ../libwkhtmltox.so libwkhtmltox.so
</code></pre><p>If you know a better way to include the file in the bin folder, please let me know.</p>
<p>That’s it! You have a fully functional Azure Functions App. Time to call it from our demo dotnet project.</p>
<h2 id="heading-how-to-invoke-the-azure-function">How to Invoke the Azure Function</h2>
<p>All said and done, we still need to test and call our function. Before we do that we need to get ahold of <em>Code</em> which is required to call the Function. </p>
<p>The <em>Code</em> is a secret that needs to be included to call the Function securely. To get the <em>Code</em> navigate to Azure Portal and open your Function App. In the side panel search for <em>Functions.</em></p>
<p><img src="https://i0.wp.com/arjavdave.com/wp-content/uploads/2021/03/Screenshot-2021-03-22-at-12.28.21-PM.png?resize=750%2C418&amp;ssl=1" alt="Image" width="600" height="400" loading="lazy">
<em>Search Functions</em></p>
<p>You will see <em>Html2Pdf</em> in the list. Click on that function which will open the details view. In the side panel there will be an option for <em>Function Keys</em>. Select that option to view a hidden default <em>Code</em> already added for you.</p>
<p><img src="https://i1.wp.com/arjavdave.com/wp-content/uploads/2021/03/Screenshot-2021-03-22-at-12.29.55-PM.png?resize=750%2C374&amp;ssl=1" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Copy the code and keep it handy since we will need it in the code. In order to test the function I have created a sample console app for you. Replace the base URL and the code is as below:</p>
<pre><code>using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Demo.ConsoleApp
{
    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
    </span>{
        public <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task Main(string[] args)
        {
            string AzureFunctionsUrl = <span class="hljs-string">"https://&lt;Your Base Url&gt;/api/Html2Pdf?code=&lt;Replace with your Code&gt;"</span>;


            using (HttpClient client = <span class="hljs-keyword">new</span> HttpClient())
            {
                <span class="hljs-keyword">var</span> Request = <span class="hljs-keyword">new</span> Html2PdfRequest
                {
                    HtmlContent = <span class="hljs-string">"&lt;h1&gt;Hello World&lt;/h1&gt;"</span>,
                    PDFFileName = <span class="hljs-string">"hello-world.pdf"</span>
                };
                string json = JsonConvert.SerializeObject(Request);
                <span class="hljs-keyword">var</span> buffer = System.Text.Encoding.UTF8.GetBytes(json);
                <span class="hljs-keyword">var</span> byteContent = <span class="hljs-keyword">new</span> ByteArrayContent(buffer);

                byteContent.Headers.ContentType = <span class="hljs-keyword">new</span> MediaTypeHeaderValue(<span class="hljs-string">"application/json"</span>);


                using (HttpResponseMessage res = <span class="hljs-keyword">await</span> client.PostAsync(AzureFunctionsUrl, byteContent))
                {
                    <span class="hljs-keyword">if</span> (res.StatusCode != HttpStatusCode.NoContent)
                    {
                        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">"There was an error uploading the pdf"</span>);
                    }
                }
            }
        }
    }

    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Html2PdfRequest</span>
    </span>{
        <span class="hljs-comment">// The HTML content that needs to be converted.</span>
        public string HtmlContent { get; set; }

        <span class="hljs-comment">// The name of the PDF file to be generated</span>
        public string PDFFileName { get; set; }
    }

}
</code></pre><p>Again the code should be pretty self-explanatory. If you have any feedback or questions just let me know. Once you run the above console app, it will create a <em>hello-world.pdf</em> file in your <em>pdf</em> container in Azure Storage.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>That concludes our tutorial on how to convert HTML to PDF using Azure Functions. Though it might be a bit difficult to setup, it is one of the cheapest solutions for going serverless. </p>
<p>Read some of my other articles here:</p>
<ul>
<li><a target="_blank" href="https://itnext.io/learn-tdd-with-integration-tests-in-net-5-0-937f126e7220">Learning Integration Tests in .NET with .TDD</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-go-passwordless-with-dotnet-identity/">Provide a password-less way to login using .NET</a></li>
<li><a target="_blank" href="https://itnext.io/net-5-how-to-authenticate-authorise-apis-correctly-34b09d132d84">How to Authenticate &amp; Authorise with .NET Identity</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-speed-up-your-website-with-azure-cdn/">How to speed up your site with Azure CDN</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Implement Azure Serverless with Blazor WebAssembly ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Introduction In this article, we will learn how to implement Azure serverless with Blazor web assembly. And to do that, we will create an app that lists out some Frequently Asked Questions (FAQ) on Covid-19.  Here's what we will cover... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-azure-serverless-with-blazor-web-assembly/</link>
                <guid isPermaLink="false">66d45db7182810487e0ce0eb</guid>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Azure Functions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blazor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ C# ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 06 Jul 2020 13:32:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c99da740569d1a4ca220f.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>In this article, we will learn how to implement Azure serverless with Blazor web assembly. And to do that, we will create an app that lists out some Frequently Asked Questions (FAQ) on Covid-19. </p>
<p>Here's what we will cover:</p>
<ul>
<li>We will create an Azure Cosmos DB which will act as our primary database to store questions and answers. </li>
<li>We will use an Azure function app to fetch data from cosmos DB. </li>
<li>We will deploy the function app to Azure to expose it globally via an API endpoint. </li>
<li>And lastly, we will consume the API in a Blazor web assembly app. </li>
</ul>
<p>The FAQs will be displayed in a card layout with the help of Bootstrap.</p>
<p>The Covid-19 FAQ app is deployed on Azure. See it in action at <a target="_blank" href="https://covid19-faq.azurewebsites.net/">https://covid19-faq.azurewebsites.net/</a></p>
<h2 id="heading-what-is-a-serverless-architecture"><strong>What is a serverless architecture?</strong></h2>
<p>In traditional applications such as a 3-tier app, a client requests resources from the server, and the server processes the request and responds with the appropriate data.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ServerArchi.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>However, there are some issues with this architecture. We need a server running continuously. Even if there are no requests, the server is present 24X7, ready to process the request. Maintaining server availability is cost-intensive. </p>
<p>Another problem is scaling. If the traffic is huge, we need to scale out all the servers which can be a cumbersome process.</p>
<p>An effective solution to this problem is serverless web architecture. The client makes a request to a file storage account instead of a server. The storage account returns the <code>index.html</code> page along with some code that needs to be rendered on the browser. </p>
<p>Since there is no server to render the page, we are relying on the browser to render the page. All the logic to draw the element or update the element will run in the browser. We do not have any server on backend – we just have a storage account with a static asset.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ServerLessArchi.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is a cost-effective solution as we do not have any server, just some static files in a storage account. It is also very easy to scale out for heavy load websites.</p>
<h2 id="heading-what-is-an-azure-function"><strong>What is an Azure function?</strong></h2>
<p>Making the browser run all the logic to render the page seems exciting, but it has some limitations. </p>
<p>We do not want the browser to make database calls. We need some part of our code to run on the server-side such as connecting to a database. </p>
<p>This is where Azure functions come in handy. In a serverless architecture, if we want some code to run the server-side, then we use an Azure function.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ServerLessArchiAZFunc.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Azure functions are an event-driven serverless compute platform. You need to pay only when execution happens. They are also easy to scale. Hence, we get both the scaling and the cost benefits with Azure functions. </p>
<p>To learn more you can refer to the <a target="_blank" href="https://azure.microsoft.com/en-in/services/functions/">Azure function official docs</a>.</p>
<h2 id="heading-why-should-you-use-azure-serverless"><strong>Why should you use Azure serverless?</strong></h2>
<p>An Azure serverless solution can add value to your product by minimizing the time and resources you spend on infrastructure-related requirements. </p>
<p>You can increase developer productivity, optimize resources and accelerate the time to market with the help of a fully managed, end-to-end Azure serverless solution.</p>
<p>To learn more, see the <a target="_blank" href="https://azure.microsoft.com/en-in/solutions/serverless/">Azure serverless official doc</a>.</p>
<h2 id="heading-what-is-blazor"><strong>What is Blazor?</strong></h2>
<p>Blazor is a .NET web framework for creating client-side applications using C#/Razor and HTML. </p>
<p>Blazor runs in the browser with the help of <a target="_blank" href="http://webassembly.org/">WebAssembly</a>. It can simplify the process of creating a single page application (SPA). It also provides a full-stack web development experience using .NET.</p>
<p>Using .NET for developing Client-side application has multiple advantages:</p>
<ul>
<li>.NET offers a range of API and tools across all platforms that are stable and easy to use.</li>
<li>The modern languages such as C# and F# offer a lot of features that make programming easier and interesting for developers.</li>
<li>The availability of one of the best IDE in the form of Visual Studio provides a great .NET development experience across multiple platforms such as Windows, Linux, and macOS.</li>
<li>.NET provides features such as speed, performance, security, scalability, and reliability in web development that makes full-stack development easier.</li>
</ul>
<h2 id="heading-why-should-you-use-blazor"><strong>Why should you use Blazor?</strong></h2>
<p>Blazor supports a wide array of features to make web development easier for us. Some of the prominent features of Blazor are:</p>
<ul>
<li><strong>Component-based architecture</strong>: Blazor provides us with a component-based architecture to create rich and composable UI.</li>
<li><strong>Dependency injection</strong>: This allows us to use services by injecting them into components.</li>
<li><strong>Layouts</strong>: We can share common UI elements (for example, menus) across pages using the layouts feature.</li>
<li><strong>Routing</strong>: We can redirect the client request from one component to another with the help of routing.</li>
<li><strong>JavaScript interop</strong>: This allows us to invoke a C# method from JavaScript, and we can call a JavaScript function or API from C# code.</li>
<li><strong>Globalization and localization</strong>: The application can be made accessible to users in multiple cultures and languages</li>
<li><strong>Live reloading</strong>: Live reloading of the app in the browser during development.</li>
<li><strong>Deployment</strong>: We can deploy the Blazor application on IIS and Azure Cloud.</li>
</ul>
<p>To learn more about Blazor, please refer to the <a target="_blank" href="http://blazor.net/">official Blazor docs</a>.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>To get started with the application, we need to fulfill these prerequisites:</p>
<ul>
<li>An Azure subscription account. You can create a free Azure account at <a target="_blank" href="https://azure.microsoft.com/en-in/free/">https://azure.microsoft.com/en-in/free/</a></li>
<li>Install the latest version of Visual Studio 2019 from <a target="_blank" href="https://visualstudio.microsoft.com/downloads/">https://visualstudio.microsoft.com/downloads/</a></li>
</ul>
<p>While installing the VS 2019, please make sure you select the Azure development and ASP.NET and web development workload.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/VSInstall.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-source-code"><strong>Source Code</strong></h2>
<p>You can get the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/azure-serverless-with-blazor">GitHub here</a>.</p>
<h2 id="heading-create-azure-cosmos-db-account"><strong>Create Azure Cosmos DB account</strong></h2>
<p>Log in to the Azure portal and search for the “Azure Cosmos DB” in the search bar and click on the result. On the next screen, click on the Add button. </p>
<p>This will open a “Create Azure Cosmos DB Account” page. You need to fill in the required information to create your database. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateCosmosDBAccount.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can fill in the details like this:</p>
<ul>
<li><strong>Subscription</strong>: Select your Azure subscription name from the drop-down.</li>
<li><strong>Resource Group</strong>: Select an existing Resource Group or create a new one.</li>
<li><strong>Account Name</strong>: Enter a unique name for your Azure Cosmos DB account. The name can contain only lowercase letters, numbers, and the ‘-‘ character, and must be between 3 and 44 characters.</li>
<li><strong>API</strong>: Select Core (SQL)</li>
<li><strong>Location</strong>: Select a location to host your Azure Cosmos DB account.</li>
</ul>
<p>Keep the other fields to its default value and click on the “Review+ Create” button. In the next screen, review all your configurations and click on the “Create” button. After a few minutes, the Azure Cosmos DB account will be created. Click on “Go to resource” to navigate to the Azure Cosmos DB account page.</p>
<h2 id="heading-set-up-the-database"><strong>Set up the Database</strong></h2>
<p>On the Azure Cosmos DB account page, click on “Data Explorer” on the left navigation, and then select “New Container”. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateContainer.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>An “Add Container” pane will open. You need to fill in the details to create a new container for your Azure Cosmos DB. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ConfigureContainer.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can fill in the details as indicated below.</p>
<ul>
<li><strong>Database ID:</strong> You can give any name to your database. Here I am using FAQDB.</li>
<li><strong>Throughput:</strong> Keep it at the default value of 400</li>
<li><strong>Container ID:</strong> Enter the name for your container. Here I am using FAQContainer.</li>
<li><strong>Partition key:</strong> The Partition key is used to automatically partition data among multiple servers for scalability. Put the value as “/id”.</li>
</ul>
<p>Click on the “OK” button to create the database.</p>
<h2 id="heading-add-sample-data-to-the-cosmos-db"><strong>Add Sample data to the Cosmos DB</strong></h2>
<p>In the Data Explorer, expand the FAQDB database then expand the FAQContainer. Select Items, and then click on New Item on the top. An editor will open on the right side of the page. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/AddItem.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Put the following JSON data in the editor and click on the Save button at the top.</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"1"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"What is corona virus?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"Corona viruses are a large family of viruses which may cause illness in animals or humans. The most recently discovered coronavirus causes coronavirus disease COVID-19."</span>
}
</code></pre>
<p>We have added a set of questions and answer along with a unique id.</p>
<p>Follow the process described above to insert five more sets of data.</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"2"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"What is COVID-19?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"COVID-19 is the infectious disease caused by the most recently discovered corona virus. This new virus and disease were unknown before the outbreak began in Wuhan, China, in December 2019."</span>
}
{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"3"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"What are the symptoms of COVID-19?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"The most common symptoms of COVID-19 are fever, tiredness, and dry cough. Some patients may have aches and pains, nasal congestion, runny nose, sore throat or diarrhea. These symptoms are usually mild and begin gradually. Some people become infected but don’t develop any symptoms and don't feel unwell."</span>
}
{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"4"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"How does COVID-19 spread?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"People can catch COVID-19 from others who have the virus. The disease can spread from person to person through small droplets from the nose or mouth which are spread when a person with COVID-19 coughs or exhales. These droplets land on objects and surfaces around the person. Other people then catch COVID-19 by touching these objects or surfaces, then touching their eyes, nose or mouth."</span>
}
{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"5"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"What can I do to protect myself and prevent the spread of disease?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"You can reduce your chances of being infected or spreading COVID-19 by taking some simple precaution. Regularly and thoroughly clean your hands with an alcoholbased hand rub or wash them with soap and water. Maintain at least 1 metre (3 feet) distance between yourself and anyone who is coughing or sneezing. Make sure you, and the people around you, follow good respiratory hygiene. This means covering your mouth and nose with your bent elbow or tissue when you cough or sneeze. Stay home if you feel unwell. If you have a fever, cough and difficulty breathing, seek medical attention and call in advance."</span>
}
{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"6"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"Are antibiotics effective in preventing or treating the COVID-19?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"No. Antibiotics do not work against viruses, they only work on bacterial infections. COVID-19 is caused by a virus, so antibiotics do not work."</span>
}
</code></pre>
<h2 id="heading-get-the-connection-string"><strong>Get the connection string</strong></h2>
<p>Click on “keys” on the left navigation, navigate to the “Read-write Keys” tab. The value under <code>PRIMARY CONNECTION STRING</code> is our required connection string. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CosmosDBContString.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Make a note of the <code>PRIMARY CONNECTION STRING</code> value. We will use it in the latter part of this article, when we will access the Azure Cosmos DB from an Azure function.</p>
<h2 id="heading-create-an-azure-function-app"><strong>Create an Azure function app</strong></h2>
<p>Open Visual Studio 2019, click on “Create a new project”. Search “Functions” in the search box. Select the Azure Functions template and click on Next. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateAzFunction.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In “Configure your new project” window, enter a Project name as <code>FAQFunctionApp</code>. Click on the Create button. Refer to the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateAzFunction_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>A new “Create a new Azure Function Application settings” window will open. Select “Azure Functions v3 (.NET Core)”from the dropdown at the top. Select the function template as “HTTP trigger”. Set the authorization level to “Anonymous” from the drop-down on the right. Click on the Create button to create the function project and HTTP trigger function. </p>
<p>Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateAzFunction_2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-install-package-for-azure-cosmos-db"><strong>Install package for Azure Cosmos DB</strong></h2>
<p>To enable the Azure function App to bind to the Azure Cosmos DB, we need to install the <code>Microsoft.Azure.WebJobs.Extensions.CosmosDB</code> package. Navigate to Tools &gt;&gt; NuGet Package Manager &gt;&gt; Package Manager Console and run the following command:</p>
<pre><code>Install-Package Microsoft.Azure.WebJobs.Extensions.CosmosDB
</code></pre><p>Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/InstallNuget.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can learn more about this package at the <a target="_blank" href="https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.CosmosDB">NuGet gallery</a>.</p>
<h2 id="heading-configure-the-azure-function-app"><strong>Configure the Azure Function App</strong></h2>
<p>The Azure function project contains a default file called <code>Function1.cs</code>. You can safely delete this file as we won’t be using this for our project.</p>
<p>Right-click on the <code>FAQFunctionApp</code> project and select Add &gt;&gt; New Folder. Name the folder as Models. Again, right-click on the Models folder and select Add &gt;&gt; Class to add a new class file. Put the name of your class as <code>FAQ.cs</code> and click Add.</p>
<p>Open <code>[FAQ.cs](https://github.com/AnkitSharma-007/azure-serverless-with-blazor/blob/master/FAQFunctionApp/FAQFunctionApp/Models/FAQ.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">namespace</span> <span class="hljs-title">FAQFunctionApp.Models</span>
{
    <span class="hljs-keyword">class</span> <span class="hljs-title">FAQ</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Question { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Answer { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>The class has the same structure as the JSON data we have inserted in the cosmos DB.</p>
<p>Right-click on the <code>FAQFunctionApp</code> project and select Add &gt;&gt; Class. Name your class as <code>[CovidFAQ.cs](https://github.com/AnkitSharma-007/azure-serverless-with-blazor/blob/master/FAQFunctionApp/FAQFunctionApp/CovidFAQ.cs)</code>. Put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">using</span> Microsoft.AspNetCore.Mvc;
<span class="hljs-keyword">using</span> System.Collections.Generic;
<span class="hljs-keyword">using</span> Microsoft.AspNetCore.Http;
<span class="hljs-keyword">using</span> Microsoft.Extensions.Logging;
<span class="hljs-keyword">using</span> Microsoft.Azure.WebJobs;
<span class="hljs-keyword">using</span> FAQFunctionApp.Models;
<span class="hljs-keyword">using</span> Microsoft.Azure.WebJobs.Extensions.Http;
<span class="hljs-keyword">using</span> System.Threading.Tasks;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">FAQFunctionApp</span>
{
    <span class="hljs-keyword">class</span> <span class="hljs-title">CovidFAQ</span>
    {
        [<span class="hljs-meta">FunctionName(<span class="hljs-meta-string">"covidFAQ"</span>)</span>]
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">Run</span>(<span class="hljs-params">
        [HttpTrigger(AuthorizationLevel.Anonymous, <span class="hljs-string">"get"</span>, Route = <span class="hljs-literal">null</span></span>)] HttpRequest req,
        [<span class="hljs-title">CosmosDB</span>(<span class="hljs-params">
            databaseName:<span class="hljs-string">"FAQDB"</span>,
            collectionName:<span class="hljs-string">"FAQContainer"</span>,
            ConnectionStringSetting = <span class="hljs-string">"DBConnectionString"</span>
            </span>)] IEnumerable&lt;FAQ&gt; questionSet, 
        ILogger log)</span>
        {
            log.LogInformation(<span class="hljs-string">"Data fetched from FAQContainer"</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> OkObjectResult(questionSet);
        }
    }
}
</code></pre>
<p>We have created a class <code>CovidFAQ</code> and added an Azure function to it. The attribute <code>FunctionName</code> is used to specify the name of the function. We have used the <code>HttpTrigger</code> attribute which allows the function to be triggered via an HTTP call. The attribute <code>CosmosDB</code> is used to connect to the Azure Cosmos DB. We have defined three parameters for this attribute as described below:</p>
<ul>
<li><strong>databaseName</strong>: the name for the cosmos DB</li>
<li><strong>collectionName</strong>: the collecting inside the cosmos DB we want to access</li>
<li><strong>ConnectionStringSetting</strong>: the connection string to connect to Cosmos DB. We will configure it in the next section.</li>
</ul>
<p>We have decorated the parameter <code>questionSet</code>, which is of type <code>IEnumerable&lt;FAQ&gt;</code> with the <code>CosmosDB</code> attribute. When the app is executed, the parameter <code>questionSet</code> will be populated with the data from Cosmos DB. The function will return the data using a new instance of <code>OkObjectResult</code>.</p>
<h2 id="heading-add-the-connection-string-to-the-azure-function"><strong>Add the connection string to the Azure Function</strong></h2>
<p>Remember the Azure cosmos DB connection string you noted earlier? Now we will configure it for our app. Open the <code>local.settings.json</code> file and add your connection string as shown below:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"IsEncrypted"</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">"Values"</span>: {
    <span class="hljs-attr">"AzureWebJobsStorage"</span>: <span class="hljs-string">"UseDevelopmentStorage=true"</span>,
    <span class="hljs-attr">"FUNCTIONS_WORKER_RUNTIME"</span>: <span class="hljs-string">"dotnet"</span>,
    <span class="hljs-attr">"DBConnectionString"</span>: <span class="hljs-string">"your connectionn string"</span>
  }
}
</code></pre>
<blockquote>
<p>The local.settings.json will not be published to Azure when we publish the Azure Function app. Therefore, we need to configure the connections string separately while publishing the app to Azure. We will see this in action in the latter part of this article.</p>
</blockquote>
<h2 id="heading-test-the-azure-function-locally"><strong>Test the Azure Function locally</strong></h2>
<p>Press F5 to execute the function. Copy the URL of your function from the Azure Functions runtime output. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ExecuteLocal-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Open the browser and paste the URL in the browser’s address bar. You can see the output as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ExecuteLocal-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here you can see the data we have inserted into our Azure Cosmos DB.</p>
<h2 id="heading-publish-the-function-app-to-azure"><strong>Publish the Function app to Azure</strong></h2>
<p>We have successfully created the Function app, but it is still running in the localhost. Let’s publish the app to make it available globally.</p>
<p>Right-click on the <code>FAQFunctionApp</code> project and select Publish. Select the Publish target as Azure.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/DeploytoAZ_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Select the specific target as “Azure Function App (windows)”.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/DeploytoAZ_2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the next window, click on the “Create a new Azure Function…” button. A new Function App window will open. Refer to the image as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/DeploytoAZ_3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can fill in the details as indicated below:</p>
<ul>
<li><strong>Name:</strong> A globally unique name for your function app.</li>
<li><strong>Subscription</strong>: Select your Azure subscription name from the drop-down.</li>
<li><strong>Resource Group</strong>: Select an existing Resource Group or create a new one.</li>
<li><strong>Plan Type</strong>: Select Consumption. It will make sure that you pay only for executions of your functions app.</li>
<li><strong>Location:</strong> Select a location for your function.</li>
<li><strong>Azure Storage</strong>: Keep the default value.</li>
</ul>
<p>Click on the “Create” button to create the Function App and return to the previous window. Make sure the option “Run from package file” is checked. Click on the Finish button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/DeploytoAZ_4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now you are at the Publish page. Click on the “Manage Azure App Service Settings” button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ManageAZappSetting.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You will see a “Application Settings” window as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/SetConnString.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>At this point, we will configure the Remote value for the “DBConnectionString” key. This value is used when the app is deployed on Azure. Since the key for Local and Remote environment is the same in our case, click on the “Insert value from Local” button to copy the value from the Local field to the Remote field. Click on the OK button.</p>
<p>You are navigated back to the Publish page. We are done with all the configurations. Click on the Publish button to publish your Azure function app. After the app is published, get the site URL value, append <code>/api/covidFAQ</code> to it and open it in the browser. You can see the output as shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ExecuteGlobally.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is the same dataset that we got while running the app locally. This proves that our serverless Azure function is deployed and able to access the Azure Cosmos DB successfully.</p>
<h2 id="heading-enable-cors-for-the-azure-app-service"><strong>Enable CORS for the Azure app service</strong></h2>
<p>We will use the Function app in a Blazor UI project. To allow the Blazor app to access the Azure Function, we need to enable CORS for the Azure app service.</p>
<p>Open the Azure portal. Navigate to “All resources”. Here, you can see the App service which we have created while Publishing the app the in previous section. Click on the resource to navigate to the resource page. Click on CORS on the left navigation. A CORS details pane will open.</p>
<p>Now we have two options here:</p>
<ol>
<li>Enter the specific origin URL to allow them to make cross-origin calls.</li>
<li>Remove all origin URL from the list, and use “*” wildcard to allow all the URL to make cross-origin calls.</li>
</ol>
<p>We will use the second option for our app. Remove all the previously listed URL and enter a single entry as “*” wildcard. Click on the Save button at the top. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/AZFuncCors.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-create-the-blazor-web-assembly-project"><strong>Create the Blazor Web assembly project</strong></h2>
<p>Open Visual Studio 2019, click on “Create a new project”. Select “Blazor App” and click on the “Next” button. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateBlazorProj_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the “Configure your new project” window, put the project name as <code>FAQUIApp</code> and click on the “Create” button as shown in the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateBlazorProj_2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the “Create a new Blazor app” window, select the “Blazor WebAssmebly App” template. Click on the Create button to create the project. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateBlazorProj_3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>To create a new razor component, right-click on the Pages folder, select Add &gt;&gt;Razor Component.An “Add New Item” dialog box will open, put the name of your component as <code>CovidFAQ.razor</code> and click on the Add button. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateRazorComp.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Open <code>[CovidFAQ.razor](https://github.com/AnkitSharma-007/azure-serverless-with-blazor/blob/master/FAQUIApp/FAQUIApp/Pages/CovidFAQ.razor)</code> and put the following code into it.</p>
<pre><code>@page <span class="hljs-string">"/covidfaq"</span>
@inject HttpClient Http

&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"d-flex justify-content-center"</span>&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"../Images/COVID_banner.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Image"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width:80%; height:300px"</span> /&gt;</span></span>
&lt;/div&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"d-flex justify-content-center"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Frequently asked Questions on Covid-19<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">hr</span> /&gt;</span></span>

@<span class="hljs-keyword">if</span> (questionList == <span class="hljs-literal">null</span>)
{
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">em</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">em</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
}
<span class="hljs-keyword">else</span>
{
    @foreach (<span class="hljs-keyword">var</span> question <span class="hljs-keyword">in</span> questionList)
    {
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card-header"</span>&gt;</span>
                @question.Question
            <span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card-body"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card-text"</span>&gt;</span>@question.Answer<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span></span>
    }
}

@code {

    private FAQ[] questionList;

    protected override <span class="hljs-keyword">async</span> Task OnInitializedAsync()
    {
        questionList = <span class="hljs-keyword">await</span> Http.GetFromJsonAsync&lt;FAQ[]&gt;(<span class="hljs-string">"https://faqfunctionapp20200611160123.azurewebsites.net/api/covidFAQ"</span>);
    }

    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FAQ</span>
    </span>{
        public string Id { get; set; }
        public string Question { get; set; }
        public string Answer { get; set; }
    }
}
</code></pre><p>In the <code>@code</code> section, we have created a class called FAQ. The structure of this class is the same as that of the FAQ class we created earlier in the Azure function app<strong>.</strong> Inside the <code>OnInitializedAsync</code> method, we are hitting the API endpoint of our function app. The data returned from the API will be stored in a variable called <code>questionList</code> which is an array of type <code>FAQ</code>.</p>
<p>In the HTML section of the page, we have set a banner image at the top of the page. The image is available in the <code>/wwwroot/Images</code> folder. We will use a foreach loop to iterate over the <code>questionList</code> array and create a bootstrap card to display the question and answer.</p>
<h2 id="heading-adding-link-to-navigation-menu"><strong>Adding Link to Navigation menu</strong></h2>
<p>The last step is to add the link of our CovidFAQ component in the navigation menu. Open <code>[/Shared/NavMenu.razor](https://github.com/AnkitSharma-007/azure-serverless-with-blazor/blob/master/FAQUIApp/FAQUIApp/Shared/NavMenu.razor#L15-L19)</code> file and add the following code into it.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-item px-3"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">NavLink</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-link"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"covidfaq"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"oi oi-plus"</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> Covid FAQ
  <span class="hljs-tag">&lt;/<span class="hljs-name">NavLink</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
</code></pre>
<p>Remove the navigation links for Counter and Fetch-data components as they are not required for this application.</p>
<h2 id="heading-execution-demo"><strong>Execution Demo</strong></h2>
<p>Press F5 to launch the app. Click on the Covid FAQ button on the nav menu on the left. You can see all the questions and answers in a beautiful card layout as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/BlazorExecution.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can also check the live app at <a target="_blank" href="https://covid19-faq.azurewebsites.net/">https://covid19-faq.azurewebsites.net/</a></p>
<h2 id="heading-summary"><strong>Summary</strong></h2>
<p>In this article, we learned about serverless and its advantage over the traditional 3-tier web architecture. We also learned how the Azure function fits in serverless web architecture. </p>
<p>To demonstrate the practical implementation of these concepts, we have created a Covid-19 FAQ app using the Blazor web assembly and Azure serverless. The questions and answers are displayed in the card layout using Bootstrap. </p>
<p>We have used the Azure cosmos DB as the primary database to store the questions and answers for our FAQ app. An Azure function is used to fetch data from the cosmos DB. We deployed the function app on Azure to make it available globally via an API endpoint.</p>
<h2 id="heading-see-also"><strong>See Also</strong></h2>
<ul>
<li><a target="_blank" href="https://ankitsharmablogs.com/optical-character-reader-using-blazor-and-computer-vision/">Optical Character Reader Using Blazor And Computer Vision</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/multi-language-translator-using-blazor-and-azure-cognitive-services/">Multi-Language Translator Using Blazor And Azure Cognitive Services</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/facebook-authentication-and-authorization-in-server-side-blazor-app/">Facebook Authentication And Authorization In Server-Side Blazor App</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/continuous-deployment-for-angular-app-using-heroku-and-github/">Continuous Deployment For Angular App Using Heroku And GitHub</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/google-authentication-and-authorization-in-server-side-blazor-app/">Google Authentication And Authorization In Server-Side Blazor App</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/blazor-crud-using-google-cloud-firestore/">Blazor CRUD Using Google Cloud Firestore</a></li>
</ul>
<p>If you like the article, share with you friends. You can also connect with me on <a target="_blank" href="https://twitter.com/ankitsharma_007">Twitter</a> and <a target="_blank" href="https://www.linkedin.com/in/ankitsharma-007/">LinkedIn</a>.</p>
<p>Originally published at <a target="_blank" href="https://ankitsharmablogs.com/">https://ankitsharmablogs.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A quick introduction to Azure function proxies ]]>
                </title>
                <description>
                    <![CDATA[ By Nadeem Ahamed In this article, we'll discuss Azure Function Proxies. They provide “Reverse Proxy Functionality” for Azure Functions. Azure Function Proxies are quite similar to Azure API management.   This post is largely inspired by Matthew Hende... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/introduction-to-azure-function-proxies/</link>
                <guid isPermaLink="false">66d4604755db48792eed3f81</guid>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Azure Functions ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 28 Aug 2019 07:36:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/08/Azure-Functions-Proxies.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Nadeem Ahamed</p>
<p>In this article, we'll discuss Azure Function Proxies. They provide “Reverse Proxy Functionality” for Azure Functions. Azure Function Proxies are quite similar to Azure API management.  </p>
<p>This post is largely inspired by Matthew Henderson the of Microsoft Azure Function Team. In his blog post, <a target="_blank" href="https://blogs.msdn.microsoft.com/appserviceteam/2017/02/22/azure-functions-proxies-public-preview/">Azure Functions Proxies public preview</a>, Matthew explains the reason behind why Microsoft came up with the ideology for Azure Function Proxies.</p>
<h2 id="heading-what-are-azure-function-proxies"><strong>What are Azure Function Proxies?</strong></h2>
<p>The basic idea behind Azure Function Proxies is that they allow us to define a single API surface for multiple function apps. Now any function app can define an endpoint that serves as a Reverse Proxy for another API. The endpoint can be a function app or it can be anything else. </p>
<p>Are you looking out for an off the shelf tool to manage and monitor your Azure Functions? <a target="_blank" href="http://bit.ly/2L6eEmM">Try this one out here for free</a>.</p>
<h2 id="heading-reason-for-implementing-azure-function-proxies"><strong>Reason for implementing Azure Function Proxies</strong></h2>
<p>For some users, it's difficult to manage large solutions with a single function app. There are a bunch of organizations using Azure Function in their micro service architecture with deployment between individual components. In this case, each function app has its own hosting, so there are many different function apps to keep track of. </p>
<p>We could also have some function app combined with another API but they could be in various different regions. So we end up passing a lot of that complexity on down to our client or consuming system.</p>
<p>Azure Function Proxies come to the rescue by providing a unified URI (Uniform Resource Identifier) which the client can actually consume. In the meantime, we can abstract all of the different function apps or other APIs and it would also enable us to build our API at a faster rate.</p>
<h2 id="heading-explanation"><strong>Explanation</strong></h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2018/07/Solution-Architecture-Diagram.png" alt="Azure Function Proxies" width="600" height="400" loading="lazy"></p>
<p>In the Solution Architecture Diagram above, we have an Azure Function Proxy followed by an Azure Function and Service Bus Queue on the back-end to store information. At the other end of the diagram, we have Data Publishers. For the purposes of this discussion, let's say that the Power Equipment generates the tag event and forwards it to Azure Functions through Proxy.</p>
<p>Initially, we create a function app by selecting the function option from the Azure portal. Here let's say we create an HTTP trigger for C# where the function of the HTTP trigger is to invoke a function with an HTTP request. </p>
<p>Now we create two functions: one is the PostTag which represents our post if we want to create a tag. The Code for the PostTag function is the following:</p>
<p><img src="https://www.serverless360.com/wp-content/uploads/2018/07/Post-Tag.png" alt="Post Tag" width="600" height="400" loading="lazy"></p>
<p>Then, we create another function called GetTag with the code specified as follows:</p>
<p><img src="https://www.serverless360.com/wp-content/uploads/2018/07/Get-Tag.png" alt="Get Tag" width="600" height="400" loading="lazy"></p>
<p>We use GetTag to pull the message from the queue, and the last tag value returns to the client.</p>
<p>We can select the link specified below to fetch the URL of both the functions. This link will provide us with a Security Token for authorization.</p>
<p><img src="https://www.serverless360.com/wp-content/uploads/2018/07/To-Get-Function-URL.png" alt="To Get Function URL" width="600" height="400" loading="lazy"></p>
<p>At this point, we move over to Function App Settings and enable the Azure Function Proxies that have the latest proxy runtime version of 0.2. Consequently, we select the “New Proxy” option from Function App Development which enables us to create two proxies. They are Proxy GetTag and Proxy PostTag. The available options in proxy are:</p>
<ul>
<li>Proxy URL</li>
<li>Route Template</li>
<li>Backend URL</li>
</ul>
<p>The URL specified in Proxy URL and the Route Template are the same regarding both the GetTag and PostTag event. The Backend URL of the Proxy GetTag will be related to the GetTag event - but for the Proxy PostTag it will be related to the PostTag event.</p>
<h2 id="heading-wrap-up">Wrap-up</h2>
<p>Azure Function Proxies are a great way to mock and test your Azure Functions endpoint even before the actual back-end development begins. Also, they can even be used in production when you need to route one URI to another.</p>
<p>I would like to conclude that Azure Function Proxies are one of the most engaging and go to market features that the Azure Functions team has provided.</p>
<p>This blog was originally published in <a target="_blank" href="http://bit.ly/2ZkPmLZ">Serverless360</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Making Sense of Azure Durable Functions ]]>
                </title>
                <description>
                    <![CDATA[ By Mikhail Shilkov Stateful Workflows on top of Stateless Serverless Cloud Functions—this is the essence of the Azure Durable Functions library. That's a lot of fancy words in one sentence, and they might be hard for the majority of readers to unders... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/making-sense-of-azure-durable-functions/</link>
                <guid isPermaLink="false">66d460428812486a37369d11</guid>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Azure Functions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 04 Jul 2019 19:46:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/07/1-0R7Wy1EJa59bvMNMHJaM4A.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Mikhail Shilkov</p>
<p>Stateful Workflows on top of Stateless Serverless Cloud Functions—this is the essence of the Azure Durable Functions library. That's a lot of fancy words in one sentence, and they might be hard for the majority of readers to understand.</p>
<p>Please join me on the journey where I'll try to explain how those buzzwords fit together. I will do this in 3 steps:</p>
<ul>
<li>Describe the context of modern cloud applications relying on serverless architecture;</li>
<li>Identify the limitations of basic approaches to composing applications out of the simple building blocks;</li>
<li>Explain the solutions that Durable Functions offer for those problems.</li>
</ul>
<h2 id="heading-microservices">Microservices</h2>
<p>Traditionally, server-side applications were built in a style which is now referred to as <strong>Monolith</strong>. If multiple people and teams were developing parts of the same application, they mostly contributed to the same code base. If the code base were structured well, it would have some distinct modules or components, and a single team would typically own each module:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/7hdmn8wjk67mbd0z8pp0.png" alt="Monolith" width="750" height="447" loading="lazy"></p>
<figcaption>Multiple components of a monolithic application</figcaption>

<p>Usually, the modules would be packaged together at build time and then deployed as a single unit, so a lot of communication between modules would stay inside the OS process.</p>
<p>Although the modules could stay loosely coupled over time, the coupling almost always occurred on the level of the data store because all teams would use a single centralized database.</p>
<p>This model works great for small- to medium-size applications, but it turns out that teams start getting in each other's way as the application grows since synchronization of contributions takes more and more effort.</p>
<p>As a complex but viable alternative, the industry came up with a revised service-oriented approach commonly called <strong>Microservices</strong>. The teams split the big application into "vertical slices" structured around the distinct business capabilities:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/mfpnrqhb9783uzv3jxm2.png" alt="Microservices" width="600" height="450" loading="lazy"></p>
<figcaption>Multiple components of a microservice-based application</figcaption>

<p>Each team then owns a whole vertical—from public communication contracts, or even UIs, down to the data storage. Explicitly shared databases are strongly discouraged. Services talk to each other via documented and versioned public contracts.</p>
<p>If the borders for the split were selected well—and that's the most tricky part—the contracts stay stable over time, and thin enough to avoid too much chattiness. This gives each team enough autonomy to innovate at their best pace and to make independent technical decisions.</p>
<p>One of the drawbacks of microservices is the change in deployment model. The services are now deployed to separate servers connected via a network:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/wgg72smliy1lgcaz8ssl.png" alt="Distributed Systems" width="550" height="436" loading="lazy"></p>
<figcaption>Challenges of communication between distributed components</figcaption>

<p>Networks are fundamentally unreliable: they work just fine most of the time, but when they fail, they fail in all kinds of unpredictable and least desirable manners. There are books written on the topic of distributed systems architecture. TL;DR: it's hard.</p>
<p>A lot of the new adopters of microservices tend to ignore such complications. REST over HTTP(S) is the dominant style of connecting microservices. Like any other synchronous communication protocol, it makes the system brittle.</p>
<p>Consider what happens when one service becomes temporary unhealthy: maybe its database goes offline, or it's struggling to keep up with the request load, or a new version of the service is being deployed. All the requests to the problematic service start failing—or worse—become very slow. The dependent service waits for the response, and thus blocks all incoming requests of its own. The error propagates upstream very quickly causing cascading failures all over the place:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/7ab7puvdzc2v0w3jo9aa.png" alt="Cascading Failures" width="480" height="265" loading="lazy"></p>
<figcaption>Error in one component causes cascading failures</figcaption>

<p>The application is down. Everybody screams and starts the blame war.</p>
<h2 id="heading-event-driven-applications">Event-Driven Applications</h2>
<p>While cascading failures of HTTP communication can be mitigated with patterns like a circuit breaker and graceful degradation, a better solution is to switch to the asynchronous style of communication as the default. Some kind of persistent queueing service is used as an intermediary.</p>
<p>The style of application architecture which is based on sending events between services is known as <strong>Event-Driven</strong>. When a service does something useful, it publishes an event—a record about the fact which happened to its business domain. Another service listens to the published events and executes its own duty in response to those facts:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/o5wml467ggim3ebfg1i4.png" alt="Event-Driven Application" width="800" height="210" loading="lazy"></p>
<figcaption>Communication in event-driven applications</figcaption>

<p>The service that produces events might not know about the consumers. New event subscribers can be introduced over time. This works better in theory than in practice, but the services tend to get coupled less.</p>
<p>More importantly, if one service is down, other services don't catch fire immediately. The upstream services keep publishing the events, which build up in the queue but can be stored safely for hours or days. The downstream services might not be doing anything useful for this particular flow, but it can stay healthy otherwise.</p>
<p>However, another potential issue comes hand-in-hand with loose coupling: low cohesion. As Martin Fowler notices in his essay
<a target="_blank" href="https://martinfowler.com/articles/201701-event-driven.html">What do you mean by "Event-Driven"</a>:</p>
<blockquote>
<p>It's very easy to make nicely decoupled systems with event notification, without realizing that you're losing sight of the larger-scale flow.</p>
</blockquote>
<p>Given many components that publish and subscribe to a large number of event types, it's easy to stop seeing the forest for the trees. Combinations of events usually constitute gradual workflows executed in time. A workflow is more than the sum of its parts, and understanding of the high-level flow is paramount to controlling the system behavior.</p>
<p>Hold this thought for a minute; we'll get back to it later. Now it's time to talk <em>cloud</em>.</p>
<h2 id="heading-cloud">Cloud</h2>
<p>The birth of public cloud changed the way we architect applications. It made many things much more straightforward: provisioning of new resources in minutes instead of months, scaling elastically based on demand, and resiliency and disaster recovery at the global scale.</p>
<p>It made other things more complicated. Here is the picture of the global Azure network:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/0kg17c6l48zwj3404yyg.png" alt="Azure Network" width="994" height="462" loading="lazy"></p>
<figcaption>Azure locations with network connections</figcaption>

<p>There are good reasons to deploy applications to more than one geographical location: among others, to reduce network latency by staying close to the customer, and to achieve resilience through geographical redundancy. Public Cloud is the ultimate distributed system. As you remember, distributed systems are hard.</p>
<p>There's more to that. Each cloud provider has dozens and dozens of managed services, which is the curse and the blessing. Specialized services are great to provide off-the-shelf solutions to common complex problems. On the flip side, each service has distinct properties regarding consistency, resiliency and fault tolerance.</p>
<p>In my opinion, at this point developers have to embrace the public cloud and apply the distributed system design on top of it. If you agree, there is an excellent way to approach it.</p>
<h2 id="heading-serverless">Serverless</h2>
<p>The slightly provocative term <strong>serverless</strong> is used to describe cloud services that do not require provisioning of VMs, instances, workers, or any other fixed capacity to run custom applications on top of them. Resources are allocated dynamically and transparently, and the cost is based on their actual consumption, rather than on pre-purchased capacity.</p>
<p>Serverless is more about operational and economical properties of the system than about the technology per se. Servers do exist, but they are someone else's concern. You don't manage the uptime of serverless applications: the cloud provider does.</p>
<p>On top of that, you pay for what you use, similar to the consumption of other commodity resources like electricity. Instead of buying a generator to power up your house, you just purchase energy from the power company. You lose some control (e.g., no way to select the voltage), but this is fine in most cases. The great benefit is no need to buy and maintain the hardware.</p>
<p>Serverless compute does the same: it supplies standard services on a pay-per-use basis.</p>
<p>If we talk more specifically about Function-as-a-Service offerings like Azure Functions, they provide a standard model to run small pieces of code in the cloud. You zip up the code or binaries and send it to Azure; Microsoft takes care of all the hardware and software required to run it. The infrastructure automatically scales up or down based on demand, and you pay per request, CPU time and memory that the application consumed. No usage—no bill.</p>
<p>However, there's always a "but". FaaS services come with an opinionated development model that applications have to follow:</p>
<ul>
<li><p><strong>Event-Driven</strong>: for each serverless function you have to define a specific trigger—the event type which causes it to run, be it an HTTP endpoint or a queue message;</p>
</li>
<li><p><strong>Short-Lived</strong>: functions can only run up to several minutes, and preferably for a few seconds or less;</p>
</li>
<li><p><strong>Stateless</strong>: as you don't control where and when function instances are provisioned or deprovisioned, there is no way to store data within the process between requests reliably; external storage has to be utilized.</p>
</li>
</ul>
<p>Frankly speaking, the majority of existing applications don't really fit into this model. If you are lucky to work on a new application (or a new module of it), you are in better shape.</p>
<p>A lot of the serverless applications may be designed to look somewhat similar to this example from <a target="_blank" href="https://www.serverless360.com/blog/building-reactive-solution-with-azure-event-grid">the Serverless360 blog</a>:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/6nmkm9cytuxdh1jmmjzo.png" alt="Serviceful Serverless Application" width="1599" height="864" loading="lazy"></p>
<figcaption>Sample application utilizing "serviceful" serverless architecture</figcaption>

<p>There are 9 managed Azure services working together in this app. Most of them have a unique purpose, but the services are all glued together with Azure Functions. An image is uploaded to Blob Storage, an Azure Function calls Vision API to recognize the license plate and send the result to Event Grid, another Azure Function puts that event to Cosmos DB, and so on.</p>
<p>This style of cloud applications is sometimes referred to as <strong>Serviceful</strong> to emphasize the heavy usage of managed services "glued" together by serverless functions.</p>
<p>Creating a comparable application without any managed services would be a much harder task, even more so, if the application has to run at scale. Moreover, there's no way to keep the pay-as-you-go pricing model in the self-service world.</p>
<p>The application pictured above is still pretty straightforward. The processes
in enterprise applications are often much more sophisticated.</p>
<p>Remember the quote from Martin Fowler about losing sight of the large-scale flow. That was true for microservices, but it's even more true for the "nanoservices" of cloud functions.</p>
<p>I want to dive deeper and give you several examples of related problems.</p>
<h2 id="heading-challenges-of-serverless-composition">Challenges of Serverless Composition</h2>
<p>For the rest of the article, I'll define an imaginary business application for booking trips to software conferences. In order to go to a conference, I need to buy tickets to the conference itself, purchase the flights, and book a room at a hotel.</p>
<p>In this scenario, it makes sense to create three Azure Functions, each one responsible for one step of the booking process. As we prefer message passing, each Function emits an event which the next function can listen for:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/nprzua8g1w231xwd47az.png" alt="Conference Booking Application" width="800" height="200" loading="lazy"></p>
<figcaption>Conference booking application</figcaption>

<p>This approach works, however, problems do exist.</p>
<h3 id="heading-flexible-sequencing">Flexible Sequencing</h3>
<p>As we need to execute the whole booking process in sequence, the Azure Functions are wired one after another by configuring the output of one function to match with the event source of the downstream function.</p>
<p>In the picture above, the functions' sequence is hard-defined. If we were to swap the order of booking the flights and reserving the hotel, that would require a code change—at least of the input/output wiring definitions, but probably also the functions' parameter types.</p>
<p>In this case, are the functions <em>really</em> decoupled?</p>
<h3 id="heading-error-handling">Error Handling</h3>
<p>What happens if the Book Flight function becomes unhealthy, perhaps due to the outage of the third-party flight-booking service? Well, that's why we use asynchronous messaging:after the function execution fails, the message returns to the queue and is picked up again by another execution.</p>
<p>However, such retries happen almost immediately for most event sources. This might not be what we want: an exponential back-off policy could be a smarter idea. At this point, the retry logic becomes <strong>stateful</strong>: the next attempt should "know" the history of previous attempts to make a decision about retry timing.</p>
<p>There are more advanced error-handling patterns too. If executions failures are not intermittent, we may decide to cancel the whole process and run compensating actions against the already completed steps.</p>
<p>An example of this is a fallback action: if the flight is not possible (e.g., no routes for this origin-destination combination), the flow could choose to book a train instead:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/1xm0gct4oqulu30xoa3y.png" alt="Fallback On Error" width="511" height="400" loading="lazy"></p>
<figcaption>Fallback after 3 consecutive failures</figcaption>

<p>This scenario is not trivial to implement with stateless functions. We could wait until a message goes to the dead-letter queue and then route it from there, but this is brittle and not expressive enough.</p>
<h3 id="heading-parallel-actions">Parallel Actions</h3>
<p>Sometimes the business process doesn't have to be sequential. In our reservation scenario, there might be no difference whether we book a flight before a hotel or vice versa. It could be desirable to run those actions in parallel.</p>
<p>Parallel execution of actions is easy with the pub-sub capabilities of an event bus: both functions should subscribe to the same event and act on it independently.</p>
<p>The problem comes when we need to reconcile the outcomes of parallel actions, e.g., calculate the final price for expense reporting purposes:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/jg39oi8g8ft0qfp3ugk4.png" alt="Fan-out / Fan-in" width="940" height="313" loading="lazy"></p>
<figcaption>Fan-out / fan-in pattern</figcaption>

<p>There is no way to implement the Report Expenses block as a single Azure Function: functions can't be triggered by two events, let alone correlate two <em>related</em> events.</p>
<p>The solution would probably include two functions, one per event, and the shared storage between them to pass information about the first completed booking to the one who completes last. All this wiring has to be implemented in custom code. The complexity grows if more than two functions need to run in parallel.</p>
<p>Also, don't forget the edge cases. What if one of the function fails? How do you make sure there is no race condition when writing and reading to/from the shared storage?</p>
<h3 id="heading-missing-orchestrator">Missing Orchestrator</h3>
<p>All these examples give us a hint that we need an additional tool to organize low-level single-purpose independent functions into high-level workflows.</p>
<p>Such a tool can be called an <strong>Orchestrator</strong> because its sole mission is to delegate work to stateless actions while maintaining the big picture and history of the flow.</p>
<p>Azure Durable Functions aims to provide such a tool.</p>
<h2 id="heading-introducing-azure-durable-functions">Introducing Azure Durable Functions</h2>
<h3 id="heading-azure-functions">Azure Functions</h3>
<p>Azure Functions is the serverless compute service from Microsoft. Functions are event-driven: each function defines a <strong>trigger</strong>—the exact definition of the event source, for instance, the name of a storage queue.</p>
<p>Azure Functions can be programmed in <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/supported-languages">several languages</a>. A basic Function with a <a target="_blank" href="https://docs.microsoft.com/azure/azure-functions/functions-bindings-storage-queue">Storage Queue trigger</a> implemented in C# would look like this: </p>
<pre><code class="lang-csharp">[<span class="hljs-meta">FunctionName(<span class="hljs-meta-string">"MyFirstFunction"</span>)</span>]
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">QueueTrigger</span>(<span class="hljs-params">
    [QueueTrigger(<span class="hljs-string">"myqueue-items"</span></span>)] <span class="hljs-keyword">string</span> myQueueItem, 
    ILogger log)</span>
{
    log.LogInformation(<span class="hljs-string">$"C# function processed: <span class="hljs-subst">{myQueueItem}</span>"</span>);
}
</code></pre>
<p>The <code>FunctionName</code> attribute exposes the C# static method as an Azure Function named <code>MyFirstFunction</code>. The <code>QueueTrigger</code> attribute defines the name of the storage queue to listen to. The function body logs the information about the incoming message.</p>
<h3 id="heading-durable-functions">Durable Functions</h3>
<p><a target="_blank" href="https://docs.microsoft.com/azure/azure-functions/durable/durable-functions-overview">Durable Functions</a> is a library that brings workflow orchestration abstractions to Azure Functions. It introduces a number of idioms and tools to define stateful, potentially long-running operations, and manages a lot of mechanics of reliable communication and state management behind the scenes.</p>
<p>The library records the history of all actions in Azure Storage services, enabling durability and resilience to failures.</p>
<p>Durable Functions is <a target="_blank" href="https://github.com/Azure/azure-functions-durable-extension">open source</a>, Microsoft accepts external contributions, and the community is quite active.</p>
<p>Currently, you can write Durable Functions in 3 programming languages: C#, F#, and Javascript (Node.js). All my examples are going to be in C#. For Javascript, check <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/durable/quickstart-js-vscode">this quickstart</a> and <a target="_blank" href="https://github.com/Azure/azure-functions-durable-extension/tree/master/samples/javascript">these samples</a>. For F# see <a target="_blank" href="https://github.com/Azure/azure-functions-durable-extension/tree/master/samples/fsharp">the samples</a>, <a target="_blank" href="https://github.com/mikhailshilkov/DurableFunctions.FSharp">the F#-specific library</a> and my article <a target="_blank" href="https://mikhail.io/2018/12/fairy-tale-of-fsharp-and-durable-functions/">A Fairy Tale of F# and Durable Functions</a>.</p>
<p>Workflow building functionality is achieved by the introduction of two additional types of triggers: Activity Functions and Orchestrator Functions.</p>
<h3 id="heading-activity-functions">Activity Functions</h3>
<p>Activity Functions are simple stateless single-purpose building blocks that do just one task and have no awareness of the bigger workflow. A new trigger type, <code>ActivityTrigger</code>, was introduced to expose functions as workflow steps, as I explain below.</p>
<p>Here is a simple Activity Function implemented in C#:</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">FunctionName(<span class="hljs-meta-string">"BookConference"</span>)</span>]
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ConfTicket <span class="hljs-title">BookConference</span>(<span class="hljs-params">[ActivityTrigger] <span class="hljs-keyword">string</span> conference</span>)</span>
{
    <span class="hljs-keyword">var</span> ticket = BookingService.Book(conference);
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ConfTicket { Code = ticket };
}
</code></pre>
<p>It has a common <code>FunctionName</code> attribute to expose the C# static method as an Azure Function named <code>BookConference</code>. The name is important because it is used to invoke the activity from orchestrators.</p>
<p>The <code>ActivityTrigger</code> attribute defines the trigger type and points to the input parameter <code>conference</code> which the activity expects to get for each invocation.</p>
<p>The function can return a result of any serializable type; my sample function returns a simple property bag called <code>ConfTicket</code>.</p>
<p>Activity Functions can do pretty much anything: call other services, load and save data from/to databases, and use any .NET libraries.</p>
<h3 id="heading-orchestrator-functions">Orchestrator Functions</h3>
<p>The Orchestrator Function is a unique concept introduced by Durable Functions. Its sole purpose is to manage the flow of execution and data among several activity functions.</p>
<p>Its most basic form chains multiple independent activities into a single
sequential workflow.</p>
<p>Let's start with an example which books a conference ticket, a flight itinerary, and a hotel room one-by-one:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/q1mogb5rtgdspw9o0p8w.png" alt="Sequential Workflow" width="700" height="403" loading="lazy"></p>
<figcaption>3 steps of a workflow executed in sequence</figcaption>

<p>The implementation of this workflow is defined by another C# Azure Function, this time with <code>OrchestrationTrigger</code>:</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">FunctionName(<span class="hljs-meta-string">"SequentialWorkflow"</span>)</span>]
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">Sequential</span>(<span class="hljs-params">[OrchestrationTrigger] DurableOrchestrationContext context</span>)</span>
{
    <span class="hljs-keyword">var</span> conference = <span class="hljs-keyword">await</span> context.CallActivityAsync&lt;ConfTicket&gt;(<span class="hljs-string">"BookConference"</span>, <span class="hljs-string">"ServerlessDays"</span>);
    <span class="hljs-keyword">var</span> flight = <span class="hljs-keyword">await</span> context.CallActivityAsync&lt;FlightTickets&gt;(<span class="hljs-string">"BookFlight"</span>, conference.Dates);
    <span class="hljs-keyword">await</span> context.CallActivityAsync(<span class="hljs-string">"BookHotel"</span>, flight.Dates);
}
</code></pre>
<p>Again, attributes are used to describe the function for the Azure runtime.</p>
<p>The only input parameter has type <code>DurableOrchestrationContext</code>. This context is the tool that enables the orchestration operations.</p>
<p>In particular, the <code>CallActivityAsync</code> method is used three times to invoke three activities one after the other. The method body looks very typical for any C# code working with a <code>Task</code>-based API. However, the behavior is entirely different. Let's have a look at the implementation details.</p>
<h2 id="heading-behind-the-scenes">Behind the Scenes</h2>
<p>Let's walk through the lifecycle of one execution of the sequential workflow above.</p>
<p>When the orchestrator starts running, the first <code>CallActivityAsync</code> invocation is made to book the conference ticket. What actually happens here is that a queue message is sent from the orchestrator to the activity function. </p>
<p>The corresponding activity function gets triggered by the queue message. It does its job (books the ticket) and returns the result. The activity function serializes the result and sends it as a queue message back to the orchestrator:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/gqiln55lyrdboph9vkct.png" alt="Durable Functions: Message Passing" width="800" height="378" loading="lazy"></p>
<figcaption>Messaging between the orchestrator and the activity</figcaption>

<p>When the message arrives, the orchestrator gets triggered again and can proceed to the secondactivity. The cycle repeats—a message gets sent to Book Flight activity, it gets triggered, does its job, and sends a message back to the orchestrator. The same message flow happens for the third call.</p>
<h3 id="heading-stop-resume-behavior">Stop-resume behavior</h3>
<p>As discussed earlier, message passing is intended to decouple the sender and receiver in time. For every message in the scenario above, no immediate response is expected. </p>
<p>On the C# level, when the <code>await</code> operator is executed, the code doesn't block the execution of the whole orchestrator. Instead, it just quits: the orchestrator stops being active and its current step completes.</p>
<p>Whenever a return message arrives from an activity, the orchestrator code restarts. It always starts with the first line. Yes, this means that the same line is executed multiple times: up to the number of messages to the orchestrator.</p>
<p>However, the orchestrator stores the history of its past executions in Azure Storage, so the effect of the second pass of the first line is different: instead of sending a message to the activity it already knows the result of that activity, so <code>await</code> returns this result back and assigns it to the <code>conference</code> variable.</p>
<p>Because of these "replays", the orchestrator's implementation has to be deterministic: don't use <code>DateTime.Now</code>, random numbers or multi-thread operations; more details <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-checkpointing-and-replay#orchestrator-code-constraints">here</a>.</p>
<h3 id="heading-event-sourcing">Event Sourcing</h3>
<p>Azure Functions are stateless, while workflows require a state to keep track of their progress. Every time a new action towards the workflow's execution happens, the framework automatically records an event in table storage.</p>
<p>Whenever an orchestrator restarts the execution because a new message arrives from its activity, it loads the complete history of this particular execution from storage. Durable Context uses this history to make decisions whether to call the activity or return the previously stored result.</p>
<p>The pattern of storing the complete history of state changes as an append-only event store is known as Event Sourcing. Event store provides several benefits:</p>
<ul>
<li><strong>Durability</strong>—if a host running an orchestration fails, the history is retained in persistent storage and is loaded by the new host where the orchestration restarts;</li>
<li><strong>Scalability</strong>—append-only writes are fast and easy to spread over multiple storage servers;</li>
<li><strong>Observability</strong>—no history is ever lost, so it's straightforward to inspect and analyze even after the workflow is complete.</li>
</ul>
<p>Here is an illustration of the notable events that get recorded during our sequential workflow:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/i56z7uddemycm69j1ey1.png" alt="Durable Functions: Event Sourcing" width="940" height="521" loading="lazy"></p>
<figcaption>Log of events in the course of orchestrator progression</figcaption>

<h3 id="heading-billing">Billing</h3>
<p>Azure Functions on the serverless consumption-based plan are billed per execution + per duration of execution.</p>
<p>The stop-replay behavior of durable orchestrators causes the single workflow "instance" to execute the same orchestrator function multiple times. This also means paying for several short executions.</p>
<p>However, the total bill usually ends up being much lower compared to the potential cost of blocking synchronous calls to activities. The price of 5 executions of 100 ms each is significantly lower than the cost of 1 execution of 30 seconds.</p>
<p>By the way, the first million executions per month are <a target="_blank" href="https://azure.microsoft.com/en-us/pricing/details/functions/">at no charge</a>, so many scenarios incur no cost at all from Azure Functions service.</p>
<p>Another cost component to keep in mind is Azure Storage. Queues and Tables that are used behind the scenes are charged to the end customer. In my experience, this charge remains close to zero for low- to medium-load applications.</p>
<p>Beware of unintentional eternal loops or indefinite recursive fan-outs in your orchestrators. Those can get expensive if you leave them out of control.</p>
<h2 id="heading-error-handling-and-retries">Error-handling and retries</h2>
<p>What happens when an error occurs somewhere in the middle of the workflow? For instance, a third-party flight booking service might not be able to process the request:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/p79a4ajxrhxh52h7cb84.png" alt="Error Handling" width="544" height="400" loading="lazy"></p>
<figcaption>One activity is unhealthy</figcaption>

<p>This situation is expected by Durable Functions. Instead of silently failing, the activity function sends a message containing the information about the error back to the orchestrator.</p>
<p>The orchestrator deserializes the error details and, at the time of replay, throws a .NET exception from the corresponding call. The developer is free to put a <code>try .. catch</code> block around the call and handle the exception:</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">FunctionName(<span class="hljs-meta-string">"SequentialWorkflow"</span>)</span>]
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">Sequential</span>(<span class="hljs-params">[OrchestrationTrigger] DurableOrchestrationContext context</span>)</span>
{
    <span class="hljs-keyword">var</span> conf = <span class="hljs-keyword">await</span> context.CallActivityAsync&lt;ConfTicket&gt;(<span class="hljs-string">"BookConference"</span>, <span class="hljs-string">"ServerlessDays"</span>);
    <span class="hljs-keyword">try</span>
    {
        <span class="hljs-keyword">var</span> itinerary = MakeItinerary(<span class="hljs-comment">/* ... */</span>);
        <span class="hljs-keyword">await</span> context.CallActivityAsync(<span class="hljs-string">"BookFlight"</span>, itinerary);
    }
    <span class="hljs-keyword">catch</span> (FunctionFailedException)
    {
        <span class="hljs-keyword">var</span> alternativeItinerary = MakeAnotherItinerary(<span class="hljs-comment">/* ... */</span>);
        <span class="hljs-keyword">await</span> context.CallActivityAsync(<span class="hljs-string">"BookFlight"</span>, alternativeItinerary);
    }
    <span class="hljs-keyword">await</span> context.CallActivityAsync(<span class="hljs-string">"BookHotel"</span>, flight.Dates);
}
</code></pre>
<p>The code above falls back to a "backup plan" of booking another itinerary. Another typical pattern would be to run a compensating activity to cancel the effects of any previous actions (un-book the conference in our case) and leave the system in a clean state.</p>
<p>Quite often, the error might be transient, so it might make sense to retry the failed operation after a pause. It's a such a common scenario that Durable Functions provides a dedicated API:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> options = <span class="hljs-keyword">new</span> RetryOptions(
    firstRetryInterval: TimeSpan.FromMinutes(<span class="hljs-number">1</span>),                    
    maxNumberOfAttempts: <span class="hljs-number">5</span>);
options.BackoffCoefficient = <span class="hljs-number">2.0</span>;

<span class="hljs-keyword">await</span> context.CallActivityWithRetryAsync(<span class="hljs-string">"BookFlight"</span>, options, itinerary);
</code></pre>
<p>The above code instructs the library to</p>
<ul>
<li>Retry up to 5 times</li>
<li>Wait for 1 minute before the first retry</li>
<li>Increase delays before every subsequent retry by the factor of 2 (1 min, 2 min, 4 min, etc.)</li>
</ul>
<p>The significant point is that, once again, the orchestrator does not block while awaiting retries. After a failed call, a message is scheduled for the moment in the future to re-run the orchestrator and retry the call.</p>
<h2 id="heading-sub-orchestrators">Sub-orchestrators</h2>
<p>Business processes may consist of numerous steps. To keep the code of orchestrators manageable, Durable Functions allows nested orchestrators. A "parent" orchestrator can call out to child orchestrators via the <code>context.CallSubOrchestratorAsync</code> method:</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">FunctionName(<span class="hljs-meta-string">"CombinedOrchestrator"</span>)</span>]
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">CombinedOrchestrator</span>(<span class="hljs-params">[OrchestrationTrigger] DurableOrchestrationContext context</span>)</span>
{
    <span class="hljs-keyword">await</span> context.CallSubOrchestratorAsync(<span class="hljs-string">"BookTrip"</span>, serverlessDaysAmsterdam);
    <span class="hljs-keyword">await</span> context.CallSubOrchestratorAsync(<span class="hljs-string">"BookTrip"</span>, serverlessDaysHamburg);
}
</code></pre>
<p>The code above books two conferences, one after the other.</p>
<h2 id="heading-fan-out-fan-in">Fan-out / Fan-in</h2>
<p>What if we want to run multiple activities in parallel?</p>
<p>For instance, in the example above, we could wish to book two conferences, but the booking order might not matter. Still, when both bookings are completed, we want to combine the results to produce an expense report for the finance department:</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/cb52udipp47s36ik71es.png" alt="Parallel Calls" width="539" height="400" loading="lazy"></p>
<figcaption>Parallel calls followed by a final step</figcaption>

<p>In this scenario, the <code>BookTrip</code> orchestrator accepts an input parameter with the name of the conference and returns the expense information. <code>ReportExpenses</code> needs to receive both expenses combined.</p>
<p>This goal can be easily achieved by scheduling two tasks (i.e., sending two messages) without awaiting them separately. We use the familiar <code>Task.WhenAll</code> method to await both and combine the results:</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">FunctionName(<span class="hljs-meta-string">"ParallelWorkflow"</span>)</span>]
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">Parallel</span>(<span class="hljs-params">[OrchestrationTrigger] DurableOrchestrationContext context</span>)</span>
{
    <span class="hljs-keyword">var</span> amsterdam = context.CallSubOrchestratorAsync(<span class="hljs-string">"BookTrip"</span>, serverlessDaysAmsterdam);
    <span class="hljs-keyword">var</span> hamburg   = context.CallSubOrchestratorAsync(<span class="hljs-string">"BookTrip"</span>, serverlessDaysHamburg);

    <span class="hljs-keyword">var</span> expenses = <span class="hljs-keyword">await</span> Task.WhenAll(amsterdam, hamburg);

    <span class="hljs-keyword">await</span> context.CallActivityAsync(<span class="hljs-string">"ReportExpenses"</span>, expenses);
}
</code></pre>
<p>Remember that awaiting the <code>WhenAll</code> method doesn't synchronously block the orchestrator. It quits the first time and then restarts two times on reply messages received from activities. The first restart quits again, and only the second restart makes it past the <code>await</code>.</p>
<p><code>Task.WhenAll</code> returns an array of results (one result per each input task), which is then passed to the reporting activity.</p>
<p>Another example of parallelization could be a workflow sending e-mails to hundreds of recipients. Such fan-out wouldn't be hard with normal queue-triggered functions: simply send hundreds of messages. However, combining the results, if required for the next step of the workflow, is quite challenging.</p>
<p>It's straightforward with a durable orchestrator:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> emailSendingTasks =
    recepients
    .Select(to =&gt; context.CallActivityAsync&lt;<span class="hljs-keyword">bool</span>&gt;(<span class="hljs-string">"SendEmail"</span>, to))
    .ToArray();

<span class="hljs-keyword">var</span> results = <span class="hljs-keyword">await</span> Task.WhenAll(emailSendingTasks);

<span class="hljs-keyword">if</span> (results.All(r =&gt; r)) { <span class="hljs-comment">/* ... */</span> }
</code></pre>
<p>Making hundreds of roundtrips to activities and back could cause numerous replays of the orchestrator. As an optimization, if multiple activity functions complete around the same time, the orchestrator may internally process several messages as a batch and restart the orchestrator function only once per batch.</p>
<h2 id="heading-other-concepts">Other Concepts</h2>
<p>There are many more patterns enabled by Durable Functions. Here is a quick list to give you some perspective:</p>
<ul>
<li>Waiting for the <em>first</em> completed task in a collection (rather than <em>all</em> of them) using the <code>Task.WhenAny</code>
method. Useful for scenarios like timeouts or competing actions.</li>
<li>Pausing the workflow for a given period or until a deadline.</li>
<li>Waiting for external events, e.g., bringing human interaction into the workflow.</li>
<li>Running recurring workflows, when the flow repeats until a certain condition is met.</li>
</ul>
<p>Further explanation and code samples are in <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview">the docs</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I firmly believe that serverless applications utilizing a broad range of managed cloud services are highly beneficial to many companies, due to both rapid development process and the properly aligned billing model.</p>
<p>Serverless tech is still young; more high-level architectural patterns need to emerge to enable expressive and composable implementations of large business systems.</p>
<p>Azure Durable Functions suggests some of the possible answers. It combines the clarity and readability of sequential RPC-style code with the power and resilience of event-driven architecture.</p>
<p><a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview">The documentation</a> for Durable Functions is excellent, with plenty of examples and how-to guides. Learn it, try it for your real-life scenarios, and let me know your opinion—I'm excited about the serverless future!</p>
<h2 id="heading-acknowledgments">Acknowledgments</h2>
<p>Many thanks to <a target="_blank" href="https://twitter.com/kashimizMSFT">Katy Shimizu</a>, <a target="_blank" href="https://twitter.com/cgillum">Chris Gillum</a>, <a target="_blank" href="https://twitter.com/efleming18">Eric Fleming</a>, <a target="_blank" href="https://twitter.com/KevinJonesD">KJ Jones</a>, <a target="_blank" href="https://twitter.com/William_DotNet">William Liebenberg</a>, <a target="_blank" href="https://twitter.com/ATosato86">Andrea Tosato</a> for reviewing the draft of this article and their valuable contributions and suggestions. </p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
