<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rick van den Bosch</title>
    <description>The latest articles on DEV Community by Rick van den Bosch (@rickvdbosch).</description>
    <link>https://dev.to/rickvdbosch</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F220873%2Fe4f61d29-92ae-4719-8ba3-e58a56f44315.jpg</url>
      <title>DEV Community: Rick van den Bosch</title>
      <link>https://dev.to/rickvdbosch</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rickvdbosch"/>
    <language>en</language>
    <item>
      <title>API Management: advanced usage quota</title>
      <dc:creator>Rick van den Bosch</dc:creator>
      <pubDate>Tue, 12 Jul 2022 09:48:23 +0000</pubDate>
      <link>https://dev.to/rickvdbosch/api-management-advanced-usage-quota-46hd</link>
      <guid>https://dev.to/rickvdbosch/api-management-advanced-usage-quota-46hd</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Azure API Management is a hybrid, multicloud management platform for APIs across all environments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For more information on API Management, check out Microsoft Docs:&lt;br&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/api-management/api-management-key-concepts"&gt;About API Management&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;API Management (APIM) is an Azure service that enables you to manage APIs as first-class assets throughout their lifecycle. It consists of an API&lt;br&gt;
&lt;em&gt;Gateway&lt;/em&gt;, a &lt;em&gt;management plane&lt;/em&gt; and a &lt;em&gt;developer portal&lt;/em&gt;. All these components are hosted in Azure and are completely managed by default.&lt;br&gt;
Each component has its own place in the ecosystem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway&lt;/strong&gt;
Acts as a façade to the backend services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Management Plane&lt;/strong&gt;
Provides full access to the API Management service capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer Portal&lt;/strong&gt;
Used to discover the APIs, onboard to use them, and learn how to consume them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EP5zl8nd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.microsoft.com/en-us/azure/api-management/media/api-management-key-concepts/api-management-components.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EP5zl8nd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.microsoft.com/en-us/azure/api-management/media/api-management-key-concepts/api-management-components.png" alt="Key components of Azure API Management" width="783" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Rate limits and quotas
&lt;/h2&gt;

&lt;p&gt;The power of APIM is that it enables you to define different types of policies on different levels, giving you lots of power on how your&lt;br&gt;
APIs are being used. For instance, you can define rate limits and quotas for your APIs. By defining and checking these in APIM, you can&lt;br&gt;
control the consumption of your APIs early; requests that exceed the rate limit or quota will be rejected at APIM level and will not even&lt;br&gt;
hit your backend service.&lt;/p&gt;

&lt;p&gt;But sometimes the built-in quotas might not be enough, forcing you to define your own. For one of our customers we had the requirement to&lt;br&gt;
have something like credit for two specific API operations. Customers would buy API-credit (separate from the product they subscribed to)&lt;br&gt;
for a specific amount of requests. Whenever the API is called, it checks to see if the customer still has credit available. If they have,&lt;br&gt;
the API is called as normal. Otherwise, the customer will get a response indicating they don't have credit and they cannot call the API&lt;br&gt;
anymore, or they need to buy more credit. This last scenario should be configurable by the sales team.&lt;/p&gt;

&lt;p&gt;Again, these credits are not connected to the product a customer subscribes to. And each customer might have different levels of credit for&lt;br&gt;
the same API operation. This flexibility combined with the requested ease of configuration made it impossible to completely manage this in&lt;br&gt;
APIM without building too complex code and/or policies.&lt;/p&gt;
&lt;h2&gt;
  
  
  The options
&lt;/h2&gt;

&lt;p&gt;Because of the expected load of the API endpoints, calling out into for instance an Azure Function to check and see if a customer still has&lt;br&gt;
credit available would not be a great fit. The intial reason for this customer to move to APIM was that they were having performance issues&lt;br&gt;
trying to store usage statistics to enable them to implement rate limiting.&lt;/p&gt;

&lt;p&gt;In the end we decided to create API middleware that would allow us to check the credit status for a specific API. But it is middleware with&lt;br&gt;
a smart addition...&lt;/p&gt;
&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;Since performance is key, and overshooting quota by a few requests is not an issue, the amount of requests and the customer credit can be&lt;br&gt;
cached in memory for a certain amount of time. At least for now. If need be we can always move it to a distributed cache like Redis. But how&lt;br&gt;
will we know the amount of requests a customer has made? This is where the&lt;br&gt;
&lt;a href="https://docs.microsoft.com/en-us/rest/api/apimanagement/"&gt;Azure API Management REST API&lt;/a&gt; comes in, and more specifically the operation&lt;br&gt;
&lt;a href="https://docs.microsoft.com/en-us/rest/api/apimanagement/current-ga/quota-by-counter-keys/list-by-service"&gt;Quota By Counter Keys - List By Service&lt;/a&gt;.&lt;br&gt;
This API ...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lists a collection of current quota counter periods associated with the counter-key configured in the policy on the specified service&lt;br&gt;
instance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means it allows us to retrieve the &lt;em&gt;Number of times Counter was called&lt;/em&gt; and even the &lt;em&gt;Data Transferred in KiloBytes&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"counterKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"xxx.xxx.xxx.xxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"periodKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SOME_PERIODKEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"periodStartTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2022-07-01T00:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"periodEndTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2022-12-31T00:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"callsCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"kbTransferred"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1796.5453825&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nextLink"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combining the information from the API Management "Quota By Counter Keys" REST API and the customer credit, we can create middleware that&lt;br&gt;
checks the credit against the number of requests made. Caching the information in the middleware is up to the user's discretion.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>api</category>
    </item>
    <item>
      <title>Building a Discord bot with Azure Logic Apps</title>
      <dc:creator>Rick van den Bosch</dc:creator>
      <pubDate>Thu, 06 May 2021 09:26:16 +0000</pubDate>
      <link>https://dev.to/rickvdbosch/building-a-discord-bot-with-azure-logic-apps-51lp</link>
      <guid>https://dev.to/rickvdbosch/building-a-discord-bot-with-azure-logic-apps-51lp</guid>
      <description>&lt;h2&gt;
  
  
  The Betatalks Discord
&lt;/h2&gt;

&lt;p&gt;A few months ago we've started a &lt;a href="https://discord.gg/KTkCXQTgjR" rel="noopener noreferrer"&gt;Betatalks Discord server&lt;/a&gt; to build a community and enable our friends to&lt;br&gt;
discuss all the Betatalks content we put out there. Think about the&lt;br&gt;
&lt;a href="https://www.youtube.com/playlist?list=PLCLCtgDNNiJR_LDx6RT8X50VrKAH3_49B" rel="noopener noreferrer"&gt;Betatalks videos&lt;/a&gt; on YouTube, Betatalks &lt;em&gt;live&lt;/em&gt; events and the&lt;br&gt;
most recent addition: &lt;a href="https://podcast.betatalks.nl/" rel="noopener noreferrer"&gt;Betatalks the podcast&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To notify the corresponding Discord channels about new Betatalks videos or Betatalks the podcast episodes, I created Azure Logic Apps to&lt;br&gt;
check for new additions and post them to the webhook. Here's how I built that.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a Discord webhook
&lt;/h2&gt;

&lt;p&gt;As Discord describes it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Webhooks are a simple way to post messages from other apps and websites into Discord using internet magic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When you create a Discord webhook you give it a name (1), select the channel the webhook posts to (2) and you optionally upload an avatar&lt;br&gt;
for the webhook (3). Once you've done all that save your changes, copy the webhook URL (4) and you should be good to go!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rickvandenbosch.net%2Fimages%2Fposts%2Fdiscord-bot-01.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rickvandenbosch.net%2Fimages%2Fposts%2Fdiscord-bot-01.webp" alt="Creating a Discord webhook"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Calling Discord webhooks
&lt;/h2&gt;

&lt;p&gt;The most basic form of calling a Discord webhook only needs either a message (in the &lt;code&gt;content&lt;/code&gt; property), file contents (in the &lt;code&gt;file&lt;/code&gt;&lt;br&gt;
property) or an array of up to 10 embed objects (in the &lt;code&gt;embeds&lt;/code&gt; property). This means a most basic, valid payload for a Discord webhook&lt;br&gt;
looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello world!"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More information on the Discord webhook payload can be found in the&lt;br&gt;
&lt;a href="https://discord.com/developers/docs/resources/webhook#execute-webhook" rel="noopener noreferrer"&gt;Discord developer portal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since calling the webhook is as easy as posting an HTTP request to an URL, you can easily test the content you're building using tools like&lt;br&gt;
&lt;a href="https://www.postman.com" rel="noopener noreferrer"&gt;Postman&lt;/a&gt;, &lt;a href="https://hoppscotch.io/" rel="noopener noreferrer"&gt;hoppscoth.io&lt;/a&gt; or Visual Studio Code using the&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=humao.rest-client" rel="noopener noreferrer"&gt;REST Client&lt;/a&gt; extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Logic App
&lt;/h2&gt;

&lt;p&gt;The podcast bot uses the RSS feed to determine if there are new episodes and calls the webhook. The YouTube one uses a&lt;br&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/connectors/apis-list" rel="noopener noreferrer"&gt;connector&lt;/a&gt; to YouTube. We'll use the latter as the example in this post.&lt;/p&gt;

&lt;h3&gt;
  
  
  Triggering the workflow
&lt;/h3&gt;

&lt;p&gt;The selected trigger for the Logic App is YouTube's "When a video is uploaded by a channel". This enables you to select any of the channels&lt;br&gt;
you've subscribed to on YouTube. You can configure how often the Logic App needs to check for new items and then the triggering part of the&lt;br&gt;
Logic App is done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rickvandenbosch.net%2Fimages%2Fposts%2Fdiscord-bot-02.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rickvandenbosch.net%2Fimages%2Fposts%2Fdiscord-bot-02.webp" alt="Triggering the workflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  On one condition
&lt;/h3&gt;

&lt;p&gt;The workflow should run on one condition. Or two actually, but they can be seen as one 😁. We only want to post content to the webhook if&lt;br&gt;
the title of the video contains the term &lt;em&gt;Betatalks&lt;/em&gt; but does not contain &lt;em&gt;podcast&lt;/em&gt;. To do this, we add a Condition-action to our workflow.&lt;br&gt;
We &lt;code&gt;toLower&lt;/code&gt; the video's title and check the conditions we just specified.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rickvandenbosch.net%2Fimages%2Fposts%2Fdiscord-bot-03.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rickvandenbosch.net%2Fimages%2Fposts%2Fdiscord-bot-03.webp" alt="Checking the condition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Calling the webhook
&lt;/h3&gt;

&lt;p&gt;Now that we've defined our trigger and checked our conditions, we can configure calling the webhook. To do so we add an HTTP action. We&lt;br&gt;
configure it to do a &lt;code&gt;POST&lt;/code&gt; to the webhook endpoint with a body we configure based on dynamic content from the trigger. As we saw in the&lt;br&gt;
example earlier we can create a json payload with a &lt;code&gt;content&lt;/code&gt; property to hold the message we want to send.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rickvandenbosch.net%2Fimages%2Fposts%2Fdiscord-bot-04.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rickvandenbosch.net%2Fimages%2Fposts%2Fdiscord-bot-04.webp" alt="Posting the information"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's it! To see the resulting messages yourself, check our &lt;a href="https://discord.gg/KTkCXQTgjR" rel="noopener noreferrer"&gt;Betatalks Discord&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hope this helps!&lt;/p&gt;

</description>
      <category>azure</category>
      <category>discord</category>
      <category>logicapps</category>
      <category>youtube</category>
    </item>
    <item>
      <title>Using Azure App Configuration in .NET 5 Functions</title>
      <dc:creator>Rick van den Bosch</dc:creator>
      <pubDate>Tue, 30 Mar 2021 15:38:57 +0000</pubDate>
      <link>https://dev.to/rickvdbosch/using-azure-app-configuration-in-net-5-functions-2joo</link>
      <guid>https://dev.to/rickvdbosch/using-azure-app-configuration-in-net-5-functions-2joo</guid>
      <description>&lt;h2&gt;
  
  
  Azure .NET 5 Functions
&lt;/h2&gt;

&lt;p&gt;A lot has been said about .NET 5 support for Azure Functions. The most important news: it is now officially supported! 🥳 To enable running&lt;br&gt;
Azure Functions with .NET 5, the new &lt;strong&gt;Isolated Model&lt;/strong&gt; enables Functions to run as an out-of-process language worker separate from the&lt;br&gt;
Azure Functions runtime. This way you'll have full control over the Function's dependencies on one hand, and new features like a middleware&lt;br&gt;
pipeline on the other. For an awesome write-up about everything around this, check out Oscar van Tol's post&lt;br&gt;
&lt;a href="https://dev.to/oscarvantol/azure-functions-in-net-5-and-beyond-26d6"&gt;Azure Functions in .NET 5 and beyond&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Azure App Configuration
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Azure App Configuration provides a service to centrally manage application settings and feature flags. Modern programs, especially programs&lt;br&gt;
running in a cloud, generally have many components that are distributed in nature. Spreading configuration settings across these components&lt;br&gt;
can lead to hard-to-troubleshoot errors during an application deployment. Use App Configuration to store all the settings for your&lt;br&gt;
application and secure their accesses in one place.&lt;br&gt;&lt;br&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/azure-app-configuration/overview"&gt;What is Azure App Configuration?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For an introduction to Azure App Configuration you can check my previous post&lt;br&gt;
&lt;a href="https://www.rickvandenbosch.net/blog/azure-app-configuration-an-introduction"&gt;Azure App Configuration: an introduction&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Bringing the two together
&lt;/h2&gt;

&lt;p&gt;To enable using App Configuration in .NET 5 Functions, you can use the &lt;code&gt;AddAzureAppConfiguration&lt;/code&gt; extension method to add App Configuration&lt;br&gt;
as a source to the &lt;code&gt;IConfigurationBuilder&lt;/code&gt;. This extension method can be found in NuGet package&lt;br&gt;
&lt;a href="https://www.nuget.org/packages/Microsoft.Extensions.Configuration.AzureAppConfiguration/"&gt;Microsoft.Extensions.Configuration.AzureAppConfiguration&lt;/a&gt;.&lt;br&gt;
By doing this, you can simply call &lt;code&gt;GetValue&lt;/code&gt; on &lt;code&gt;IConfiguration&lt;/code&gt; to get a value. Based on the order you add configuration sources to the&lt;br&gt;
builder, you will be able to fallback through different source.&lt;/p&gt;

&lt;p&gt;For example: if you first add Environment Variables (which includes settings.json files, too!) and add App Configuration second, asking for&lt;br&gt;
a setting 'Setting1' will first try to get that value from App Configuration. If it can't be found there, the application will search for&lt;br&gt;
the setting 'Setting1' in Environment variables.&lt;/p&gt;
&lt;h3&gt;
  
  
  Wiring up your Functions App
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Program.cs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HostBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureAppConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Add Environment Variables since we need to get the App Configuration connection string from settings.&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddEnvironmentVariables&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="c1"&gt;// Call Build() so we can get values from the IConfiguration.&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;connectionString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"AppConfigurationConnectionString"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// Add Azure App Configuration with the connectionstring.&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAzureAppConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureFunctionsWorkerDefaults&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Getting a value from App Configuration in a Function
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Triggered.cs&lt;/code&gt; (an HttpTriggered Function):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Triggered&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Private field to hold IConfiguration&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IConfiguration&lt;/span&gt; &lt;span class="n"&gt;_configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Constructor that gets IConfiguration injected&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Triggered&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IConfiguration&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_configuration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Triggered"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;HttpResponseData&lt;/span&gt; &lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;HttpTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthorizationLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="n"&gt;HttpRequestData&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;FunctionContext&lt;/span&gt; &lt;span class="n"&gt;executionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"text/plain; charset=utf-8"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Call GetVallue&amp;lt;string&amp;gt; on IConfiguration to get the setting, this calls out to App Configuration&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;settingOne&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"Setting1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"The value of the setting is &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;settingOne&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I tried this with a complete connection string, so including the access key. Of course this can also work without an access key using a&lt;br&gt;
&lt;a href="https://www.theurlist.com/managedidentity"&gt;Managed Identity&lt;/a&gt;. This eliminates the need for having access keys in code or configuration.&lt;/p&gt;

&lt;p&gt;Hope this helps. Happy coding!&lt;/p&gt;

</description>
      <category>azure</category>
      <category>dotnet</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Azure Static Web Apps: UPDATE</title>
      <dc:creator>Rick van den Bosch</dc:creator>
      <pubDate>Sun, 28 Mar 2021 09:38:41 +0000</pubDate>
      <link>https://dev.to/rickvdbosch/azure-static-web-apps-update-3g6g</link>
      <guid>https://dev.to/rickvdbosch/azure-static-web-apps-update-3g6g</guid>
      <description>&lt;p&gt;After my two previous posts &lt;a href="https://www.rickvandenbosch.net/blog/azure-static-web-apps-a-first-look"&gt;Azure Static Web Apps: a first look&lt;/a&gt; and&lt;br&gt;
&lt;a href="https://www.rickvandenbosch.net/blog/azure-static-web-apps-quirks-gotchas"&gt;Azure Static Web Apps: quirks &amp;amp; gotchas&lt;/a&gt;, let's have an &lt;em&gt;updated look&lt;/em&gt; at ASWA in this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support for new languages 👩🏻‍💻
&lt;/h2&gt;

&lt;p&gt;Announced at &lt;a href="https://myignite.microsoft.com/"&gt;Microsoft Ignite&lt;/a&gt; this year,&lt;br&gt;
&lt;a href="https://azure.microsoft.com/en-us/updates/blazor-and-c-sharp-apis-now-supported-in-azure-static-web-apps/"&gt;Blazor and C# APIs now supported in Azure Static Web Apps&lt;/a&gt;.&lt;br&gt;
This enables .NET developers to build and deploy full stack .NET applications with Static Web Apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blazor support
&lt;/h3&gt;

&lt;p&gt;Since ASWA is a static hosting option, which means we don't have a server component*, the Blazor support for ASWA means support for Blazor &lt;strong&gt;WebAssembly&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://webassembly.org/"&gt;webassembly.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;* &lt;em&gt;Yes, I know. Serving files is normally also done by a server. But in this case we're talking about a server as a machine that executes server-side code for a web application. With Wasm, we don't need this.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  C# Functions support
&lt;/h3&gt;

&lt;p&gt;We can now build C# Functions as the API behind our static web app! I've done so to test out the functionality, more details on that under&lt;br&gt;
'Taking it for a spin'. &lt;/p&gt;

&lt;h3&gt;
  
  
  🐍 Python Functions support
&lt;/h3&gt;

&lt;p&gt;ASWA now &lt;em&gt;also&lt;/em&gt; supports Python as your language of choice for building APIs as the backend for your static website.&lt;/p&gt;

&lt;p&gt;With these languages now being supported, developers using JavaScript, C#, and Python can use ASWA to automatically build and deploy full&lt;br&gt;
stack applications from a GitHub repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Metrics 📉
&lt;/h2&gt;

&lt;p&gt;As far as metrics go: it improved. However, we're not there yet. It now &lt;em&gt;is&lt;/em&gt; possible to see metrics like Requests, Function Hits and&lt;br&gt;
Function errors. Unfortunately I was not able to see any details after drilling into logs. This made me track down an error in my Function &lt;br&gt;
that turned out to be caused by a typo for way longer than I care to admit. 😳&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SyGY7W_o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.rickvandenbosch.net/images/posts/aswa-metrics.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SyGY7W_o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.rickvandenbosch.net/images/posts/aswa-metrics.webp" alt="metrics!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration 📃
&lt;/h2&gt;

&lt;p&gt;Although configuration for ASWA hasn't changed, I now had a reason to play with it. The C# Functions API I created for the Blazor&lt;br&gt;
WebAssembly frontend needed a setting to connect to the right Storage Account. So I needed to add that setting to the Configuration tab. If&lt;br&gt;
you've worked with C# Functions before, you know it has a need for a setting called &lt;code&gt;AzureWebJobsStorage&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Because I got a 500-error from the Function, I thought it might be because of the missing &lt;code&gt;AzureWebJobsStorage&lt;/code&gt; so I added it. This didn't&lt;br&gt;
solve my issue (as said earlier I made a typo in another setting) but when I went back to remove it to keep things clean &lt;strong&gt;the setting was&lt;br&gt;
gone!&lt;/strong&gt; Seems like ASWA adds that setting for you, making sure your Functions will run.&lt;/p&gt;

&lt;p&gt;So there's probably a storage account somewhere that's associated with my ASWA. Question is; will I be able to read the value for the&lt;br&gt;
&lt;code&gt;AzureWebJobsStorage&lt;/code&gt; setting from my Function? And if so,will I be able to store information there? I might dive into that later 😇&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking it for a spin 🔄
&lt;/h2&gt;

&lt;p&gt;I created a fairly simple solution with a Blazor WebAssembly frontend, a &lt;code&gt;Common&lt;/code&gt; project for entities and a C# Functions project for the&lt;br&gt;
API my frontend would talk to. This is not the cleanest implementation (since Table Entities are sent to the frontend) but it gets the &lt;br&gt;
example done. The entire solution is available on GitHub in the &lt;a href="https://github.com/rickvdbosch/aswa-example02"&gt;rickvdbosch/aswa-example02&lt;/a&gt;&lt;br&gt;
repository. The result can be found at &lt;a href="https://blue-water-047654a03.azurestaticapps.net/"&gt;blue-water-047654a03&lt;/a&gt;. If you go to the 'Fetch &lt;br&gt;
data' page, it will get some blogposts on static web apps from Table Storage through the C# Functions API.&lt;/p&gt;

&lt;p&gt;When you're using C# Functions, they too are available at &lt;code&gt;&amp;lt;aswa-url&amp;gt;/api/&amp;lt;function-name&amp;gt;&lt;/code&gt;, so you can access them from the frontend without&lt;br&gt;
too much hassle.&lt;/p&gt;

&lt;p&gt;Creating the ASWA is the same as it used to be, however this time I could select Blazor as a frontend framework. For the API I just&lt;br&gt;
specified the folder that contained the C# Functions and the GitHub workflow to build and deploy them was automatically created. The &lt;br&gt;
contents of that workflow, which is of course available in the repo as well, looked the same as the one that was created for the JavaScript&lt;br&gt;
Functions. That probably means the &lt;code&gt;Azure/static-web-apps-deploy@v0.0.1-preview&lt;/code&gt; task determines what needs to be done on the fly?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion and resources 🔗
&lt;/h2&gt;

&lt;p&gt;This is the first (big) update on Static Web Apps since the launch of their Preview at Build earlier this year. At first I felt like they&lt;br&gt;
rushed it to announce at Build, and then had other things to attend to. Fortunately, we have Blazor and C# support now 🤓&lt;/p&gt;

&lt;p&gt;Microsoft is actively listening to feedback. I even got an answer of the program manager of Azure Functions &amp;amp; Azure Static Web Apps about&lt;br&gt;
the &lt;a href="https://dev.to/blog/azure-static-web-apps-quirks-gotchas/"&gt;quirks and gotchas post&lt;/a&gt;. It is &lt;em&gt;very&lt;/em&gt; nice to see the improvevements to ASWA. And then to&lt;br&gt;
think it's still only a preview ... 🤯&lt;/p&gt;

&lt;p&gt;Some interesting links to be found here:&lt;br&gt;&lt;br&gt;
&lt;a href="https://azure.microsoft.com/en-us/updates/blazor-and-c-sharp-apis-now-supported-in-azure-static-web-apps/"&gt;Blazor and C# APIs now supported in Azure Static Web Apps&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/static-web-apps/deploy-blazor"&gt;Tutorial: Building a static web app with Blazor in Azure Static Web Apps&lt;/a&gt;  &lt;/p&gt;

</description>
      <category>azure</category>
    </item>
    <item>
      <title>Making Serverless (do the) work for you</title>
      <dc:creator>Rick van den Bosch</dc:creator>
      <pubDate>Thu, 12 Sep 2019 22:37:20 +0000</pubDate>
      <link>https://dev.to/rickvdbosch/making-serverless-do-the-work-for-you-1ha8</link>
      <guid>https://dev.to/rickvdbosch/making-serverless-do-the-work-for-you-1ha8</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;This article is part of &lt;a href="https://dev.to/azure/serverless-september-content-collection-2fhb"&gt;#ServerlessSeptember&lt;/a&gt;. You'll find other helpful articles, detailed tutorials, and videos in this all-things-Serverless content collection. New articles are published every day — that's right, every day — from community members and cloud advocates in the month of September. &lt;/p&gt;

&lt;p&gt;Find out more about how Microsoft Azure enables your Serverless functions at &lt;a href="https://docs.microsoft.com/azure/azure-functions/?WT.mc_id=servsept_devto-blog-cxa" rel="noopener noreferrer"&gt;https://docs.microsoft.com/azure/azure-functions/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serverless
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fk368cct16hov4c6zj97u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fk368cct16hov4c6zj97u.jpg" alt="Serverless: Aaaaand it's gone"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Serverless is &lt;em&gt;hot&lt;/em&gt;. If you Google the term 'Serverless' you get &lt;a href="https://www.google.com/search?q=serverless" rel="noopener noreferrer"&gt;almost 9.5 million results&lt;/a&gt;. The &lt;a href="https://en.wikipedia.org/wiki/Serverless_computing" rel="noopener noreferrer"&gt;Serverless computing Wikipedia page&lt;/a&gt; was created on July 10 2016 and currently has a total of 289 edits. That’s an average of one edit every 4 days. The three major cloud vendors (Amazon, Google and Microsoft) all have a Serverless landing page in place. And if you look at the Google Trends chart for worldwide searches for the term 'Serverless', you’ll see that it has been on a steady incline since early 2016.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fsymyq8f4xc5avrq9jvmh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fsymyq8f4xc5avrq9jvmh.png" alt="Google Trends: Serverless, Worldwide"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Serverless doesn't mean there aren't any servers. It doesn't mean there are &lt;em&gt;less&lt;/em&gt; servers. It just means you don't have to &lt;em&gt;manage&lt;/em&gt; them, since they are abstracted away by the platform. From both a Dev and an Ops perspective, there &lt;em&gt;are no servers&lt;/em&gt;. But we all know they're out there...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Just like wireless internet has wires somewhere, serverless architectures still have servers somewhere.&lt;br&gt;&lt;br&gt;
What ‘serverless’ really means is that, as a developer you don’t have to think about those servers. You just focus on code.&lt;/em&gt;&lt;br&gt;&lt;br&gt;
— &lt;a href="https://serverless.com/learn/overview/" rel="noopener noreferrer"&gt;serverless.com&lt;/a&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Serverless in Azure
&lt;/h2&gt;

&lt;p&gt;My personal experience is more geared towards Azure, so I have a bit more in-depth knowledge of how Serverless is available there. The most obvious Serverless service Microsoft Azure provides is &lt;a href="https://azure.microsoft.com/en-us/services/functions/" rel="noopener noreferrer"&gt;Azure Functions&lt;/a&gt;. These are set out to “accelerate and simplify application development with serverless compute”. And they do just that.&lt;/p&gt;

&lt;p&gt;Have a look at the &lt;a href="https://serverlesslibrary.net/" rel="noopener noreferrer"&gt;Azure Serverless Community Library&lt;/a&gt; which, at the time of writing this, has 98 examples of just how simple it is to get things done with Azure Functions. And an overall count of 115 serverless examples.&lt;/p&gt;

&lt;p&gt;But Serverless in Microsoft Azure doesn’t end with Azure Functions. The thing is.... it’s not entirely clear where it &lt;em&gt;does&lt;/em&gt; end. Different pages on azure.com have different summaries of all serverless services.  &lt;/p&gt;

&lt;p&gt;If you look at the list on the &lt;a href="https://azure.microsoft.com/en-us/solutions/serverless/" rel="noopener noreferrer"&gt;Azure serverless&lt;/a&gt; page, they define these categories for their serverless services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compute&lt;/li&gt;
&lt;li&gt;Workflows and integration&lt;/li&gt;
&lt;li&gt;DevOps and developer tools&lt;/li&gt;
&lt;li&gt;AI and machine learning&lt;/li&gt;
&lt;li&gt;Database&lt;/li&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;li&gt;Monitoring&lt;/li&gt;
&lt;li&gt;Analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You could question if for instance storage or monitoring are Serverless or PaaS. Or maybe even SaaS…? But when you look at the Compute category you see something that I think is just wrong. Azure App Service is mentioned as a Serverless offering. While with App Service, you specify the tier in which to run the application. Determining number of cores, available memory and.... wait a minute...! I’m specifying a server to run this thing on!!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdglq6rxfjiq7wu1v3fzc.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdglq6rxfjiq7wu1v3fzc.jpeg" alt="Serverless All the Things!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since Serverless is &lt;em&gt;hot&lt;/em&gt;, we're naming &lt;em&gt;everything&lt;/em&gt; serverless!&lt;/p&gt;

&lt;p&gt;We've already seen there are a LOT of Serverless services or products available on Azure. I would like to dive in to a few of them...&lt;/p&gt;

&lt;h3&gt;
  
  
  Flow &amp;amp; Logic Apps
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://flow.microsoft.com/en-us/" rel="noopener noreferrer"&gt;Microsoft Flow&lt;/a&gt; and &lt;a href="https://azure.microsoft.com/en-us/services/logic-apps/" rel="noopener noreferrer"&gt;Azure Logic Apps&lt;/a&gt; are quite similar. They're both &lt;em&gt;configuration first integration services&lt;/em&gt;. Both of them use the same designer, too. As a matter of fact, Microsoft Flow is built &lt;em&gt;on top of&lt;/em&gt; Logic Apps.&lt;br&gt;&lt;br&gt;
And where Microsoft Flow "&lt;em&gt;empowers any office worker to perform simple integrations&lt;/em&gt;", Logic Apps "&lt;em&gt;enable advanced or mission-critical integrations&lt;/em&gt;" and are a part of Azure.  &lt;/p&gt;

&lt;p&gt;The designers of both Flow and Logic Apps show a bit of that distinction. In the image below, the bright part on the left is Microsoft Flow, the dark part on the right is the Logic App. Both of them are triggered though a tweet with the text '#Serverless". Both of them do sentiment detection using cognitive services. But where the Flow only shows the basics, Logic Apps already shows more options for customization.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxbj8vctdyswsaxc6lcc6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxbj8vctdyswsaxc6lcc6.jpg" alt="Microsoft Flow and Logic Apps side by side"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These simple pieces of code, of &lt;em&gt;logic&lt;/em&gt;, are triggered by the connector or schedule you select and are really easy to create. I've heard people compare it to &lt;a href="https://ifttt.com/" rel="noopener noreferrer"&gt;IFTTT&lt;/a&gt;.  &lt;/p&gt;
&lt;h3&gt;
  
  
  Azure Functions
&lt;/h3&gt;

&lt;p&gt;After using Azure Functions quite extensively I can say: they deliver on their promise. In the beginning. developing Functions was only for those who could find their way in pieces of documentation and a LOT of example code. The entire development lifecycle has been streamlined the past couple of years, including anything that has to do with (local) debugging. The &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local" rel="noopener noreferrer"&gt;Azure Functions Core Tools&lt;/a&gt; enable you to run your Functions locally and debug them just like you would any other wpplication. And it has ASCII art, too!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fp2pafvpm1ga8ayhjvtj9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fp2pafvpm1ga8ayhjvtj9.png" alt="Azure Functions Core Tools, including cool ASCII art 🤓"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The different development environments for Azure Functions are visible as soon as you create an Azure Function App in the &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure portal&lt;/a&gt; and you click the plus-sign to add a function. You can choose &lt;em&gt;Visual Studio&lt;/em&gt;, &lt;em&gt;VS Code&lt;/em&gt;, &lt;em&gt;Any Editor + Core tools&lt;/em&gt; or &lt;em&gt;In-Portal&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The In-Portal experience enables you to do everything you need to do to get an Azure Function up and running &lt;em&gt;right there in the Azure Portal&lt;/em&gt;. After you've selected In-Portal, the system will ask you what kind of template you would like to use. The next step is to write the code needed for your Function. And again, this can be done entirely in the Azure Portal using &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp" rel="noopener noreferrer"&gt;C# Script (.csx)&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The .csx format allows you to write less "boilerplate" and focus on writing just a C# function. Instead of wrapping everything in a namespace and class, just define a &lt;em&gt;Run&lt;/em&gt; method.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This experience is close to the experience you get when using Microsoft Flow and Azure Logic Apps, although in this situation you actually need some programming knowledge to get the function to do what you want it to do since you need to write the code yourself.&lt;/p&gt;
&lt;h4&gt;
  
  
  Triggers &amp;amp; Bindings
&lt;/h4&gt;

&lt;p&gt;Where Serverless compute abstracts away the underlying infrastructure for you, using triggers &amp;amp; bindings abstracts away the &lt;em&gt;external resources&lt;/em&gt; you're connecting to.  &lt;/p&gt;

&lt;p&gt;Consider this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;BlobTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"upload/{name}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Connection&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"scs"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;addedBlob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"copied/{name}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileAccess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Connection&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"scs"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;addedBlob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CopyToAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's only one (that's &lt;strong&gt;1&lt;/strong&gt;) &lt;em&gt;actual line of code&lt;/em&gt; in this example, the rest is just &lt;em&gt;configuring&lt;/em&gt; the triggers and bindings. And although it's just one line of code, there's a LOT that happens: This code is automatically triggerd when a new blob is added to a specific container, making the stream to the new blob available immediately. You also get the name if the added blob, and a new stream in a separate container pointing to a blob with the same name as the uploaded one. And of course, the contents of one blob are copied to the other.&lt;br&gt;&lt;br&gt;
Now imagine the boilerplate code you would have to write if you want to develop this without the power of the cloud. Or 5 years ago... 😲&lt;/p&gt;

&lt;p&gt;Let's break down the code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;BlobTrigger&lt;/code&gt; line states: trigger this Function when there's a new Blob in the 'upload' container and pass its &lt;code&gt;name&lt;/code&gt; and a &lt;code&gt;Stream 'addedBlob'&lt;/code&gt; for it into the Function.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Blob&lt;/code&gt; binding states: create a blob in the 'copied' container with the same name and pass a &lt;code&gt;Stream 'stream'&lt;/code&gt; for it into the Function.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;string 'name'&lt;/code&gt; contains the name of the added blob that causes the Trigger, the &lt;code&gt;ILogger log&lt;/code&gt; is a logging mechanism the platform passes in.&lt;/li&gt;
&lt;li&gt;The call to &lt;code&gt;CopyToAsync&lt;/code&gt; is the &lt;em&gt;one actual line of code&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is so much going on here, with so little code. The platform manages a TON of stuff for you, enabling you to focus on what matters. And there's even more where this came from, enabling developers to &lt;em&gt;finally&lt;/em&gt; focus on adding business value to code, instead of writing boilerplate code to, for instance, connect to a resource. For a full and up to date list of supported bindings see..... &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings#supported-bindings" rel="noopener noreferrer"&gt;Supported bindings&lt;/a&gt; 🤭&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Sidenote&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;By the way, talking about the platform managing stuff for you... If you're using Key Vault to store application secrets, have a look at using a &lt;a href="https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview" rel="noopener noreferrer"&gt;Managed Identities for Azure Resources&lt;/a&gt; to connect to the Key Vault. Better yet, have a look at &lt;a href="https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references" rel="noopener noreferrer"&gt;Key Vault references&lt;/a&gt;. It enables you to work with secrets from Azure Key Vault in your App Service or Azure Functions application &lt;em&gt;without requiring any code changes&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Azure Storage
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Azure Storage is a Microsoft-managed service providing cloud storage that is highly available, secure, durable, scalable, and redundant. Azure Storage includes Azure Blobs (objects), Azure Data Lake Storage Gen2, Azure Files, Azure Queues, and Azure Tables.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So Azure Storage is more than just blobs. Azure storage enables you to ingest data from anywhere, even at the edge. There are several cost-effective options to retain data. You can have security features in place to safeguard data and control access and of course wrangle data with a broad library of supported tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flpwkkelpgmmm3kn0wksr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flpwkkelpgmmm3kn0wksr.png" alt="Azure Storage: Not Just Blobs!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Static website hosting
&lt;/h4&gt;

&lt;p&gt;Next to the normal* things Azure Storage facilitates, it also has a nice added feature: &lt;a href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website" rel="noopener noreferrer"&gt;Static Website Hosting&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can serve static content (HTML, CSS, JavaScript, and image files) directly from a storage container named $web. Hosting your content in Azure Storage enables you to use serverless architectures that include Azure Functions and other Platform as a service (PaaS) services.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Content in the &lt;em&gt;$web&lt;/em&gt; container are served through anonymous requests, only available through object read operations and &lt;strong&gt;case-sensitive&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Static website hosting is available at no extra charge. Of course you &lt;em&gt;are&lt;/em&gt; billed for the blob storage that your site utilizes and the operations costs.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Sidenote&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;* We're already calling everything Azure Storage is providing 'normal'. But it isn't. Read &lt;a href="https://docs.microsoft.com/en-us/azure/storage/common/storage-scalability-targets" rel="noopener noreferrer"&gt;Azure Storage scalability and performance targets for storage accounts&lt;/a&gt;, then determine if it's normal... 😲&lt;/p&gt;

&lt;h3&gt;
  
  
  Azure Event Grid
&lt;/h3&gt;

&lt;p&gt;The next (logical?) step in Serverless architectures are event-based architectures. Event Grid made events a first-class citizen in Azure. Where triggers might get lazy (since they rely on a form of polling), events are instant. In comes Event Grid: it has built-in support for events coming from Azure services, like storage blobs and resource groups. Event Grid also has support for your own events, using custom topics.&lt;/p&gt;

&lt;p&gt;The flow inside Event Grid is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A publisher decides to send events to Event Grid&lt;/li&gt;
&lt;li&gt;An event takes place in an event source&lt;/li&gt;
&lt;li&gt;The source sends the event to a topic&lt;/li&gt;
&lt;li&gt;A subscription to a topic means you're interested in a specific type of event&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fc5d277nwj43capuy1zok.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fc5d277nwj43capuy1zok.png" alt="Azure Event Grid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Event Grid supports both Event Grid events and &lt;a href="https://cloudevents.io/" rel="noopener noreferrer"&gt;Cloud events&lt;/a&gt;, a specification for describing event data in a common way.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Azure Event Grid is one of the first public cloud services with available support for CloudEvents, so you can now publish and consume events using both CloudEvents and Azure native events schemas. This means today you can pump Azure Storage events in CloudEvents format into the serverless platform of your choice for handling, or you can ingest events from other cloud platform’s services publishing CloudEvents into the Azure platform and process them on your beloved Azure Functions or Logic Apps already connected to Event Grid. All natively done, with no custom code involved.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;While writing this I've already thought of a lot of other stuff I also found worth mentioning, since there is so much cool stuff going on in the (Azure) cloud. Especially around Serverless and developer productivity. The platform is managing more and more for us as developers enabling us to focus on actually adding value.&lt;/p&gt;

&lt;p&gt;So the title "Making Serverless do the work for you" actually means two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Serverless enables your &lt;em&gt;applications&lt;/em&gt; to rapidly scale with little to no up-front costs&lt;/li&gt;
&lt;li&gt;Serverless enables your &lt;em&gt;developers&lt;/em&gt; to leverage the power of the platform, making them (even) more productive&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm not sure about you, but I'm making Serverless do the work for me... 😉&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;You can find some examples in the GitHub repo &lt;a href="https://github.com/rickvdbosch/mswfy" rel="noopener noreferrer"&gt;Making Serverless Work For You&lt;/a&gt;. More context might be found in my articles &lt;a href="https://www.rickvandenbosch.net/blog/using-triggers-bindings-in-azure-functions-v2/" rel="noopener noreferrer"&gt;Using Triggers &amp;amp; Bindings in Azure Functions V2&lt;/a&gt; and &lt;a href="https://dev.toe"&gt;Dynamic output bindings in Azure Functions&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Disclaimer&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The numbers in this article have been updated on Thursday September 12&lt;sup&gt;th&lt;/sup&gt; 2019. They give a general feel of the order of magnitude. I'm not aiming at keeping them updated, so if you're reading this at a (much) later point in time, make sure to check the numbers before basing important (business) decisions on them. 🤓&lt;/p&gt;

&lt;p&gt;One other thing: do Serverless if it &lt;em&gt;fits&lt;/em&gt;. Don't do it because it's hip. Don't use it because everyone else is. Use it because it's the best choice for the situation. And if it isn't, don't!&lt;/p&gt;

</description>
      <category>azure</category>
      <category>serverless</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Using Triggers &amp; Bindings in Azure Functions V2</title>
      <dc:creator>Rick van den Bosch</dc:creator>
      <pubDate>Fri, 30 Aug 2019 08:18:17 +0000</pubDate>
      <link>https://dev.to/rickvdbosch/using-triggers-bindings-in-azure-functions-v2-1nk1</link>
      <guid>https://dev.to/rickvdbosch/using-triggers-bindings-in-azure-functions-v2-1nk1</guid>
      <description>&lt;p&gt;To start things off: yes. There’s some pretty decent documentation on all the available Triggers &amp;amp; Bindings in Azure Functions. Like this &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings"&gt;overview page&lt;/a&gt;. And you can also find documentation on specific bindings, like the &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus"&gt;Service Bus Binding&lt;/a&gt;. Nevertheless, I wanted to add to that documentation with some simple, real-world examples using triggers &amp;amp; bindings. So here goes.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Writing to Blob Storage
&lt;/h2&gt;

&lt;p&gt;Consider this very simple &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob#trigger"&gt;BlobTrigger&lt;/a&gt;ed Azure Function. It copies the triggering file into a different container in Azure Blob Storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static async Task Run(
    [BlobTrigger("upload/{name}", Connection = "scs")]Stream addedBlob, 
    string name, ILogger log)
{
    // Setting up my BlobStorageRepository (it's a wrapper)
    var connectionString = Environment.GetEnvironmentVariable("scs", EnvironmentVariableTarget.Process);
    var blobStorageRepository = new BlobStorageRepository(connectionString);

    await blobStorageRepository.AddFileAsync("copied", name, addedBlob);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks like a decent solution. But bindings can make this code so much simpler!&lt;br&gt;&lt;br&gt;
Consider the next code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static async Task Run(
    [BlobTrigger("upload/{name}", Connection = "scs")]Stream addedBlob,
    [Blob("copied/{name}", FileAccess.Write, Connection = "scs")]Stream stream,
    string name, ILogger log)
 {
    await addedBlob.CopyToAsync(stream);
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result here is the same! By using the out binding, you can directly access the stream in the “copied” container. And you can use the “name” parameter from the input binding.  &lt;/p&gt;

&lt;p&gt;Next to that, it’s not just Stream you can bind to. For the out bindings, here’s the list of types you can bind to (taken from &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob#output---usage"&gt;this article&lt;/a&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TextWriter&lt;/li&gt;
&lt;li&gt;out string&lt;/li&gt;
&lt;li&gt;out byte[]&lt;/li&gt;
&lt;li&gt;CloudBlobStream&lt;/li&gt;
&lt;li&gt;Stream&lt;/li&gt;
&lt;li&gt;CloudBlobContainer&lt;/li&gt;
&lt;li&gt;CloudBlobDirectory&lt;/li&gt;
&lt;li&gt;ICloudBlob&lt;/li&gt;
&lt;li&gt;CloudBlockBlob&lt;/li&gt;
&lt;li&gt;CloudPageBlob&lt;/li&gt;
&lt;li&gt;CloudAppendBlob&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means you can also bind against, for instance, a CloudBlobContainer to output multiple blobs.&lt;/p&gt;

&lt;p&gt;Putting messages on a Service Bus&lt;br&gt;
When it comes to Blobs, chances are you wouldn’t want to write a large amount of them based on one trigger. Although I can think of some scenario’s...&lt;br&gt;&lt;br&gt;
For Service Bus however, this scenario is far more likely. Lets have a look at how we can implement that using a ServiceBusBinding. The below Function reads a file. It then splits the contents on a space, and puts every word on a Service Bus queue as a separated message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void Run(
    [BlobTrigger("to-process/{name}", Connection = "scs")]Stream addedBlob,
    [ServiceBus("process", Connection = "sbcss", EntityType = EntityType.Queue)] ICollector queueCollector,
    string name, ILogger log)
{
    using (var reader = new StreamReader(addedBlob))
    {
        var words = (await reader.ReadToEndAsync()).Split(' ');
        Parallel.ForEach(words.Distinct(), (word) =&amp;gt;     
        {
            queueCollector.Add(word);     
        }); 
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that almost feels like magic ? Almost everything is abstracted away for you: connecting and writing to a Service Bus are not even your concern anymore.&lt;br&gt;
For Service Bus out bindings, the types you can bind to are (taken from &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus#output---usage"&gt;here&lt;/a&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;out T paramName&lt;/li&gt;
&lt;li&gt;out string&lt;/li&gt;
&lt;li&gt;out byte[]&lt;/li&gt;
&lt;li&gt;out Message&lt;/li&gt;
&lt;li&gt;ICollector or IAsyncCollector&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ICollector and IAsyncCollector are for creating multiple messages. A message is created when you call the Add method. In async functions, use the return value or IAsyncCollector instead of an out parameter.&lt;/p&gt;

&lt;p&gt;The IAsyncCollector.AddAsync() behavior depends on the type of binding you’re using&amp;gt; And on whether or not the underlying service supports batches. If the service does, calling AddAsync only prepares the items. In that case, calling FlushAsync() actually flushes them. When a function completes successfully, FlushAsync() will be called automatically.&lt;/p&gt;

&lt;p&gt;The services that currently support batching:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SendGrid&lt;/li&gt;
&lt;li&gt;Twilio&lt;/li&gt;
&lt;li&gt;EventHub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s an open issue on GitHub that states they Need to drive consistency for IAsyncCollector batching across bindings. Something to keep an eye on.&lt;/p&gt;

&lt;p&gt;Hope this helps.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://www.rickvandenbosch.net/blog/using-triggers-bindings-in-azure-functions-v2/"&gt;rickvandenbosch.net&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>serverless</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
