<?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>Forem: Maxime Rouiller</title>
    <description>The latest articles on Forem by Maxime Rouiller (@maximrouiller).</description>
    <link>https://forem.com/maximrouiller</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%2F73416%2Feeead2e5-7ff4-4877-b765-e66c8bf1e226.jpg</url>
      <title>Forem: Maxime Rouiller</title>
      <link>https://forem.com/maximrouiller</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/maximrouiller"/>
    <language>en</language>
    <item>
      <title>1-Click Deployment of Cognitive Services with ARM Templates</title>
      <dc:creator>Maxime Rouiller</dc:creator>
      <pubDate>Sat, 04 Apr 2020 15:30:00 +0000</pubDate>
      <link>https://forem.com/azure/1-click-deployment-of-cognitive-services-with-arm-templates-1hjd</link>
      <guid>https://forem.com/azure/1-click-deployment-of-cognitive-services-with-arm-templates-1hjd</guid>
      <description>&lt;p&gt;I've been using Cognitive Services for a while now. I'm creating AI services for hackathons, personal projects, or actual work.&lt;/p&gt;

&lt;p&gt;One of the scenarios I'm always facing is to create the service initially. It requires you first to find the right service, then chooses a region, then a pricing tier. Could all of this be made simpler? I think so!&lt;/p&gt;

&lt;p&gt;If, like me, you are only using the free tier and are trying to publish into an EastUS/WestUS region, then I'm ready to show you how to do this!&lt;/p&gt;

&lt;p&gt;There is a feature in Azure that allows us to create templates for resources. They are called Azure Resource Manager Templates. They are also known as ARM Templates. At a bare minimum, those templates are a combination of a template file and a parameter file.&lt;/p&gt;

&lt;p&gt;The template file defines the resources that we need to create while the parameters allow you to set variables at deployment time. You can use the template directly with the Azure Portal and fill the parameters there. Alternatively, you can create a set of parameters in a file and deploy those resources with a Command-Line. Isn't that powerful?&lt;/p&gt;

&lt;p&gt;The best use for us at the moment, however, is to reduce the number of choices. We're going to build a single-click deployment option for us to use later on.&lt;/p&gt;

&lt;p&gt;Let me show you the repository I created for &lt;a href="https://github.com/MaximRouiller/OneClickCognitiveServices"&gt;One-Click Cognitive Services deployment&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's take a look at our templates to identify how we are deploying them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"contentVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&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;"baseName"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"defaultValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"computervision"&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;"location"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"defaultValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eastus"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"allowedValues"&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="s2"&gt;"eastus"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"westus"&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;"apiType"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"defaultValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ComputerVision"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"allowedValues"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="s2"&gt;"ComputerVision"&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;"sku"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"defaultValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"F0"&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;"resources"&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;"apiVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2017-04-18"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[concat(parameters('baseName'), uniqueString(resourceGroup().id))]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[parameters('location')]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Microsoft.CognitiveServices/accounts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[parameters('apiType')]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"sku"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[parameters('sku')]"&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;"properties"&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;"customSubDomainName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[concat(parameters('baseName'), uniqueString(resourceGroup().id))]"&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="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;There's a lot to unpack here. There are 3 sections in that file: &lt;code&gt;parameters&lt;/code&gt;, &lt;code&gt;variables&lt;/code&gt;, and &lt;code&gt;resources&lt;/code&gt;. We're not going to use the &lt;code&gt;variables&lt;/code&gt;, and &lt;code&gt;parameters&lt;/code&gt; is self-describing. Let's look at &lt;code&gt;resources&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, it's an array, which means that we are can create multiple resources at the same time. For the resource we selected, Computer Vision, let's look at the resource structure.  &lt;/p&gt;

&lt;p&gt;Excluding whitespaces and sub-properties, there are only around seven meaningful lines in there. Let's go through them.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apiVersion&lt;/code&gt; is representing the version of the resource provider we use internally. It affects the available properties and schema.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;name&lt;/code&gt; is representing your resource name. Here, we are building a unique name using the &lt;code&gt;uniqueString&lt;/code&gt; function to ensure we're not creating duplicates within a same Resource Group.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;location&lt;/code&gt; is representing the deployed region of the service. From the default values, we are only letting EastUS and WestUS as options. For a complete list of locations, here's the &lt;a href="https://azure.microsoft.com/global-infrastructure/services/?products=cognitive-services&amp;amp;WT.mc_id=aiapril-blog-marouill"&gt;reference page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;type&lt;/code&gt; is representing the actual service we are deploying. For Cognitive Services, it's all the same type. The attribute &lt;code&gt;kind&lt;/code&gt; specify which service we want.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kind&lt;/code&gt; is representing what kind of cognitive services we want to deploy. There are many available and is listed by running the Azure CLI command &lt;a href="https://docs.microsoft.com/cli/azure/cognitiveservices/account?view=azure-cli-latest&amp;amp;WT.mc_id=aiapril-blog-marouill#az-cognitiveservices-account-list-kinds"&gt;&lt;code&gt;az cognitiveservices account list-kinds -o table&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sku&lt;/code&gt; is representing the amount we want to pay. We are selecting F0 here by default since we want the free option.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;customSubDomainName&lt;/code&gt; represents the domain name we can enable for token authentication. &lt;/p&gt;

&lt;p&gt;With that, we can deploy cognitive services with the click of a button within any subscription on Azure.&lt;/p&gt;

&lt;p&gt;If you are interested in a follow-up article, please let me know in the comments or &lt;a href="https://twitter.com/MaximRouiller"&gt;on Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aiml</category>
      <category>azure</category>
      <category>deployment</category>
    </item>
    <item>
      <title>September 2019 .NET/ASP.NET Documentation Update</title>
      <dc:creator>Maxime Rouiller</dc:creator>
      <pubDate>Fri, 04 Oct 2019 14:01:31 +0000</pubDate>
      <link>https://forem.com/maximrouiller/september-2019-net-asp-net-documentation-update-3lk5</link>
      <guid>https://forem.com/maximrouiller/september-2019-net-asp-net-documentation-update-3lk5</guid>
      <description>&lt;p&gt;&lt;strong&gt;TLDR; This is a status update on the .NET documentation. If you want me to do more of those (once a month), please let me know in the comments!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comment: If you have suggestions, please let me know in the comments. Any product feedback will be forwarded to the proper product team.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hi everyone!&lt;/p&gt;

&lt;p&gt;This is the fourth month where I post a summary of all .NET-related documentation that was significantly updated. This month covers all changes from September 1st to September 27th.&lt;/p&gt;

&lt;p&gt;My name is Maxime Rouiller and I’m a Cloud Advocate with Microsoft. For this month, I’m covering three major products:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.NET, which had ~474 commits, and 3,492 changed files on their &lt;a href="https://github.com/dotnet/docs"&gt;docs repository&lt;/a&gt; and ~96 PRs on their &lt;a href="https://github.com/dotnet/dotnet-api-docs"&gt;API docs repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ASP.NET, which had ~282 commits, and 1,102 changed files on their &lt;a href="https://github.com/aspnet/AspNetCore.Docs"&gt;docs repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NuGet, which had ~109 commits, and 45 changed files on their &lt;a href="https://github.com/NuGet/docs.microsoft.com-nuget"&gt;docs repository&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this month, I’ll be trying something new. I will not be leaving a comment beside each article and will instead use a Legend with emojis (I know, it’s Reddit. What am I doing!?). Thing is, it’s easier to show you what’s what than explain it. Where relevant, I will leave notes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Legend
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📢: Major/Main article that everyone will want to read&lt;/li&gt;
&lt;li&gt;💥: Important/Must read.&lt;/li&gt;
&lt;li&gt;✨: Brand new page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: It’s not because a page doesn’t have an icon that it is not important. Everything here is either brand new or significantly modified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Themes this month
&lt;/h2&gt;

&lt;h3&gt;
  
  
  .NET Core 3.0
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;What’s new for Preview 9 and GA release&lt;/li&gt;
&lt;li&gt;JSON serialization&lt;/li&gt;
&lt;li&gt;CLI updates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Managed Languages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;C# 8.0 Updates&lt;/li&gt;
&lt;li&gt;C# 8.0 Spec updates&lt;/li&gt;
&lt;li&gt;✨&lt;a href="https://github.com/dotnet/try-samples/tree/master/101-linq-samples"&gt;101 LINQ samples in your browser&lt;/a&gt;. Through the magic of try.net, Blazor, and Roslyn, you can explore LINQ using a dotnet global tool. See the &lt;a href="https://github.com/dotnet/try-samples"&gt;try-samples home page&lt;/a&gt; for installation instructions and more samples. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  .NET Core
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;💥 &lt;a href="https://docs.microsoft.com/dotnet/core/windows-prerequisites?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Prerequisites for .NET Core on Windows&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💥 &lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/3.0.9-3.0?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Breaking changes, version 3.0 Preview 9 to 3.0 - .NET Core&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  E-book - Blazor for Web Forms Developers (Preview) ✨
&lt;/h3&gt;

&lt;p&gt;Are you a Web Forms developer? This book is brand new and will help you bridge your knowledge between Web Forms and Blazor.&lt;/p&gt;

&lt;p&gt;More content should be coming in the next few months.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❗ Don’t forget that you can download all e-books with the &lt;strong&gt;Download PDF&lt;/strong&gt; button in the bottom left of your screen (desktop) or through the &lt;code&gt;Content&lt;/code&gt; menu if you are on mobile. ❗&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/architecture/blazor-for-web-forms-developers/index?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Blazor for ASP.NET Web Forms Developers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  E-book - Architecting Cloud Native .NET Applications for Azure (Preview)
&lt;/h3&gt;

&lt;p&gt;Are you a developer, a lead or even an architect? Do you want to know how to build an application that is made for the cloud?&lt;/p&gt;

&lt;p&gt;This is the book for you.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❗ Don’t forget that you can download all e-books with the &lt;strong&gt;Download PDF&lt;/strong&gt; button in the bottom left of your screen (desktop) or through the &lt;code&gt;Content&lt;/code&gt; menu if you are on mobile. ❗&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/architecture/cloud-native/?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Architecting Cloud Native .NET Applications for Azure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  E-book - ASP.NET Core gRPC for WCF Developers (Preview) 💥✨
&lt;/h3&gt;

&lt;p&gt;Lots of you have asked me last month about how to handle gRPC coming from a WCF point of view. Well, this month is your time to shine. There’s a literal book being currently written about it. The whole thing is brand new and is aimed at developers that were, surprise surprise, using WCF before.&lt;/p&gt;

&lt;p&gt;This book takes you from migration, load balancing, Kubernetes, error handling, security, and to why even use it. It’s a must-read.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❗ Don’t forget that you can download all e-books with the &lt;strong&gt;Download PDF&lt;/strong&gt; button in the bottom left of your screen (desktop) or through the &lt;code&gt;Content&lt;/code&gt; menu if you are on mobile. ❗&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/architecture/grpc-for-wcf-developers/index?wt.mc_id=docsexp4_devto-blog-marouill"&gt;ASP.NET Core gRPC for WCF Developers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Compatibility 💥
&lt;/h3&gt;

&lt;p&gt;When you’re upgrading your app from one version of .NET Core to another, you might be interested to know if there were any compatibility changes introduced that could impact your app. The list is not final yet so there will be more breaking changes added in the next few months. You have the option to look at them by version or feature area:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/breaking-changes?wt.mc_id=docsexp4_devto-blog-marouill"&gt;.NET Core breaking changes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/2.2-3.0?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Breaking changes, version 2.2 to 3.0 - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/3.0.6-3.0.7?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Breaking changes, version 3.0 Preview 6 to 3.0 Preview 7 - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/3.0.7-3.0.8?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Breaking changes, version 3.0 Preview 7 to 3.0 Preview 8 - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/3.0.8-3.0.9?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Breaking changes, version 3.0 Preview 8 to 3.0 Preview 9 - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/3.0.9-3.0?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Breaking changes, version 3.0 Preview 9 to 3.0 - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/corefx?wt.mc_id=docsexp4_devto-blog-marouill"&gt;CoreFx breaking changes - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/crypto?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Cryptography breaking changes, version 2.2 to 3.0 - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/cryptography?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Cryptography breaking changes - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/framework-core?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Breaking changes, .NET Framework to .NET Core 3.0 - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/globalization?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Globalization breaking changes - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/visualbasic?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Visual Basic breaking changes - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/core/compatibility/winforms?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Windows Forms breaking changes - .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Desktop Guide for Windows Presentation Foundation (WPF) 💥✨
&lt;/h3&gt;

&lt;p&gt;We’re revamping the WPF content and giving it a new home called “Desktop Guide”. This guide will cover WPF for both .NET Core and .NET Framework, with an emphasis on .NET Core. This guide will continue to grow over time as the team modernizes and bring more relevant content into it.&lt;/p&gt;

&lt;p&gt;Whether you like XAML or not, it’s a good thing to remember as there are tons of WPF applications in the wild and your chances of encountering one is mostly guaranteed.&lt;/p&gt;

&lt;p&gt;This guide may save you some time in the future.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/desktop-wpf/overview/index?wt.mc_id=docsexp4_devto-blog-marouill"&gt;What is Windows Presentation Foundation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/desktop-wpf/migration/differences-from-net-framework?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Differences between .NET Framework and .NET Core WPF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/desktop-wpf/migration/convert-project-from-net-framework?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Migrating WPF Apps to .NET Core 3.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/desktop-wpf/fundamentals/xaml?wt.mc_id=docsexp4_devto-blog-marouill"&gt;XAML Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/desktop-wpf/fundamentals/xaml-resources-define?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Define XAML resources for WPF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/desktop-wpf/fundamentals/styles-templates-overview?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Styles and templates in WPF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/desktop-wpf/fundamentals/styles-templates-create-apply-style?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Create a style for a control in WPF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/desktop-wpf/data/data-binding-overview?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Data binding overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  .NET Framework
&lt;/h3&gt;

&lt;p&gt;Updates to the actual .NET Framework content. Not Core related.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/framework/app-domains/build-multifile-assembly?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Build a multifile assembly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/framework/app-domains/build-single-file-assembly?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Build a .NET Framework single-file assembly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/framework/app-domains/how-to-share-an-assembly-with-other-applications?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Share an assembly with other applications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/framework/reflection-and-codedom/get-type-member-information?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Get type and member information by using reflection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  .NET Guide - Assemblies in .NET
&lt;/h3&gt;

&lt;p&gt;Everything you ever wanted or didn’t want to know about assemblies in .NET. To sign or not to sign isn’t the question. Did you know? That is the question.&lt;/p&gt;

&lt;p&gt;The assemblies content used to be in the .NET Framework guide and was now moved to where our .NET Fundamentals content live. It’s now applicable to both .NET Framework and .NET Core.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/index?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Assemblies in .NET&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/contents?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Assembly contents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/create-public-private-key-pair?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Create a public-private key pair&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/create-signed-friend?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Create signed friend assemblies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/create-unsigned-friend?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Create unsigned friend assemblies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/delay-sign?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Delay-sign an assembly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/embed-types-visual-studio?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Walkthrough: Embed types from managed assemblies in Visual Studio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/find-fully-qualified-name?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Find an assembly’s fully qualified name&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/friend?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Friend assemblies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/identify?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Determine if a file is an assembly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/load-unload?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Load and unload assemblies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/reference-strong-named?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Reference a strong-named assembly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/assembly/sign-strong-name?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: Sign an assembly with a strong name&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tooling, tutorial, serialization, exceptions, and others
&lt;/h3&gt;

&lt;p&gt;Machine learning tutorial? Yes. We haven’t gotten enough of them that’s for sure. Machine learning is becoming omnipresent and starting with a tutorial sure is a good way to learn.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/machine-learning/tutorials/text-classification-tf?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Tutorial: Analyze sentiment of movie reviews using a pre-trained TensorFlow model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/machine-learning/how-to-guides/load-data-ml-net?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Load data from files and other sources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The JSON serializer is brand new. Have you tried it? Those articles are your perfect start to understanding how it works. Including the most fun data type to serialize, &lt;code&gt;DateTime&lt;/code&gt; and &lt;code&gt;DateTimeOffset&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/serialization/system-text-json-how-to?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to serialize JSON - .NET&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/serialization/system-text-json-overview?wt.mc_id=docsexp4_devto-blog-marouill"&gt;JSON serialization in .NET&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/dotnet/standard/datetime/system-text-json-support?wt.mc_id=docsexp4_devto-blog-marouill"&gt;DateTime and DateTimeOffset support in System.Text.Json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the new tooling and .NET being used on the daily, you’re bound to run into issues. The first article handles the possible issues you might run into. The second shows you how to make localized exception messages. Neat 🤖📷.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✨ &lt;a href="https://docs.microsoft.com/dotnet/core/tools/troubleshoot-usage-issues?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Troubleshoot .NET Core tool usage issues&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✨ &lt;a href="https://docs.microsoft.com/dotnet/standard/exceptions/how-to-create-localized-exception-messages?wt.mc_id=docsexp4_devto-blog-marouill"&gt;How to: create user-defined exceptions with localized exception messages&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ASP.NET Core
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📢 &lt;a href="https://docs.microsoft.com/aspnet/core/release-notes/aspnetcore-3.0?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;What’s new in ASP.NET Core 3.0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💥 &lt;a href="https://docs.microsoft.com/aspnet/core/migration/22-to-30?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Migrate from ASP.NET Core 2.2 to 3.0&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;If you are now reading this, it’s because you are a fan of WebAssembly(aka WASM). Enjoy this small update.&lt;/p&gt;

&lt;p&gt;Server-side Blazor has hit GA while the client-side is still in Preview.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/blazor/components?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Create and use ASP.NET Core Razor components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/blazor/hosting-models?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;ASP.NET Core Blazor hosting models&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fundamentals
&lt;/h3&gt;

&lt;p&gt;Lots of fundamental articles have been updated to the 3.0 release.&lt;/p&gt;

&lt;p&gt;You will find here updated articles, samples, and general tidying of articles (typos, more snippets, clarifications).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/fundamentals/change-tokens?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Detect changes with change tokens in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/fundamentals/dependency-injection?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Dependency injection in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/fundamentals/host/hosted-services?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Background tasks with hosted services in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/fundamentals/metapackage-app?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Microsoft.AspNetCore.App metapackage for ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/fundamentals/middleware/extensibility-third-party-container?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Middleware activation with a third-party container in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/fundamentals/middleware/extensibility?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Factory-based middleware activation in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/fundamentals/middleware/index?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;ASP.NET Core Middleware&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/fundamentals/routing?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Routing in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/fundamentals/servers/kestrel?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Kestrel web server implementation in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  gRPC
&lt;/h3&gt;

&lt;p&gt;So you’re not the &lt;em&gt;book&lt;/em&gt; kind of developer. You’d rather jump in the code and try right away. I get that. After you get up to date as to what is gRPC on .NET Core, we’re getting right into how to integrate with gRPC services. Straight to the code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/grpc/index?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Introduction to gRPC on .NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;✨ &lt;a href="https://docs.microsoft.com/aspnet/core/grpc/client?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Call gRPC services with the .NET client&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✨ &lt;a href="https://docs.microsoft.com/aspnet/core/grpc/clientfactory?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;gRPC client factory integration in .NET Core&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✨ &lt;a href="https://docs.microsoft.com/aspnet/core/grpc/diagnostics?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Logging and diagnostics in gRPC on .NET&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  MVC
&lt;/h3&gt;

&lt;p&gt;Updated article about testing controller logic. Finally, there were some docs missing about Tag Helpers. This is now a solved problem. See below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/mvc/controllers/testing?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Test controller logic in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;✨ &lt;a href="https://docs.microsoft.com/aspnet/core/mvc/views/tag-helpers/built-in/link-tag-helper?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Link Tag Helper in ASP.NET Core&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✨ &lt;a href="https://docs.microsoft.com/aspnet/core/mvc/views/tag-helpers/built-in/script-tag-helper?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Script Tag Helper in ASP.NET Core&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SignalR
&lt;/h3&gt;

&lt;p&gt;We were missing a page about what feature each of our client supports. Check out the brand new page below. Then, since SignalR has dropped &lt;code&gt;UseSignalR()&lt;/code&gt; everywhere and you now need to use &lt;code&gt;UseEndpoints(...)&lt;/code&gt;, all of our docs now accurately represent how to set this up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✨ &lt;a href="https://docs.microsoft.com/aspnet/core/signalr/client-features?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;SignalR client features&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/signalr/authn-and-authz?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Authentication and authorization in ASP.NET Core SignalR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/signalr/background-services?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Host ASP.NET Core SignalR in background services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/signalr/configuration?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;ASP.NET Core SignalR configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/signalr/security?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Security considerations in ASP.NET Core SignalR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/tutorials/signalr-typescript-webpack?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Use ASP.NET Core SignalR with TypeScript and Webpack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  WebAPI
&lt;/h3&gt;

&lt;p&gt;After releasing the &lt;code&gt;Microsoft.dotnet-openapi&lt;/code&gt; global tool, it is important to have documentation for it. That’s in the first article. A new article on customizing your error handling with ASP.NET Core Web API is definitely a must-read as well.&lt;/p&gt;

&lt;p&gt;For the rest, you will find here updated samples, and general tidying of articles (typos, more snippets, clarifications).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✨ &lt;a href="https://docs.microsoft.com/aspnet/core/web-api/Microsoft.dotnet-openapi?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Develop ASP.NET Core apps using OpenAPI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✨ &lt;a href="https://docs.microsoft.com/aspnet/core/web-api/handle-errors?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Handle errors in ASP.NET Core web APIs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/web-api/action-return-types?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Controller action return types in ASP.NET Core web API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/web-api/advanced/formatting?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Format response data in ASP.NET Core Web API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/web-api/index?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Create web APIs with ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Host and Deploy
&lt;/h3&gt;

&lt;p&gt;Tons of updates on hosting with the new release of 3.0 in GA. With the release of Blazor Server-Side, this documentation also needed major updates. If you are using Blazor today, make sure to read this to avoid problems in the future. Health checks now get wrapped under &lt;code&gt;UseEndpoints&lt;/code&gt; which required its documentation to be changed as well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/host-and-deploy/aspnet-core-module?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;ASP.NET Core Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;💥 &lt;a href="https://docs.microsoft.com/aspnet/core/host-and-deploy/blazor/index?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Host and deploy ASP.NET Core Blazor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/host-and-deploy/health-checks?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Health checks in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;Updated package names and new snippets.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/performance/caching/distributed?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Distributed caching in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Razor Pages
&lt;/h3&gt;

&lt;p&gt;The introduction has been completely rewritten with new code snippets for 3.0. Worth taking the time to refresh your knowledge on Razor Pages.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💥 &lt;a href="https://docs.microsoft.com/aspnet/core/razor-pages/index?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Introduction to Razor Pages in ASP.NET Core&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/razor-pages/ui-class?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Reusable Razor UI in class libraries with ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;Updated for &lt;code&gt;UseEndpoints()&lt;/code&gt; as well as including new API updates for 3.0. Updated documentation troubleshoot certification update.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/security/authentication/cookie?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Use cookie authentication without ASP.NET Core Identity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/security/cors?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Enable Cross-Origin Requests (CORS) in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/security/enforcing-ssl?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Enforce HTTPS in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tests
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/aspnet/core/test/integration-tests?wt.mc_id=docsexp4_devto-blog-marouill&amp;amp;view=aspnetcore-3.0"&gt;Integration tests in ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  NuGet
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📢 &lt;a href="https://docs.microsoft.com/nuget/release-notes/NuGet-5.3?wt.mc_id=docsexp4_devto-blog-marouill"&gt;NuGet 5.3 Release Notes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💥 &lt;a href="https://docs.microsoft.com/nuget/nuget-org/Deprecate-packages?wt.mc_id=docsexp4_devto-blog-marouill"&gt;Deprecating packages on nuget.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reference
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/nuget/reference/nuspec?wt.mc_id=docsexp4_devto-blog-marouill"&gt;.nuspec File Reference for NuGet&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;deprecating &lt;code&gt;iconUrl&lt;/code&gt;, adding &lt;code&gt;icon&lt;/code&gt; to replace it.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/nuget/reference/msbuild-targets?wt.mc_id=docsexp4_devto-blog-marouill"&gt;NuGet pack and restore as MSBuild targets&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;adding instruction on how to pack an &lt;code&gt;icon&lt;/code&gt; within your package&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>documentation</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Using EasyAuth (AppService Authentication) with ASP.NET Core</title>
      <dc:creator>Maxime Rouiller</dc:creator>
      <pubDate>Tue, 09 Jul 2019 17:15:00 +0000</pubDate>
      <link>https://forem.com/azure/using-easyauth-appservice-authentication-with-asp-net-core-1cj1</link>
      <guid>https://forem.com/azure/using-easyauth-appservice-authentication-with-asp-net-core-1cj1</guid>
      <description>&lt;p&gt;There's this cool feature in Azure AppService that I love. It's called EasyAuth although it may not use that name anymore.&lt;/p&gt;

&lt;p&gt;When you are creating a project and want to throw in some quick authentication Single-Sign-On (SSO for short) is a great way to throw the authentication problem at someone else while you keep on working on delivering value.&lt;/p&gt;

&lt;p&gt;Of course, you can get a clear understanding of &lt;a href="https://docs.microsoft.com/azure/app-service/overview-authentication-authorization?WT.mc_id=devto-blog-marouill#how-it-works"&gt;how it works&lt;/a&gt;, but I think I can summarize quite quickly.&lt;/p&gt;

&lt;p&gt;EasyAuth works by intercepting the authentication requests (&lt;code&gt;/.auth/*&lt;/code&gt;) or when authenticated, fills in the user context within your application. That's the 5-second pitch.&lt;/p&gt;

&lt;p&gt;Now, the &lt;a href="https://support.microsoft.com/help/307985/info-asp-net-http-modules-and-http-handlers-overview?WT.mc_id=devto-blog-marouill"&gt;.NET Framework application lifecycle&lt;/a&gt; allowed tons of stuff to happen when you added an &lt;code&gt;HttpModule&lt;/code&gt; in your application. You had access to everything and the kitchen sink.&lt;/p&gt;

&lt;p&gt;.NET Core, on the other hand, removed the concept of all-powerful modules and instead introduced &lt;a href="https://docs.microsoft.com/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.0&amp;amp;WT.mc_id=devto-blog-marouill"&gt;Middlewares&lt;/a&gt;. Instead of relying on a fixed set of events happening in a pipeline, we could expand the pipeline as our application needed it.&lt;/p&gt;

&lt;p&gt;I'm not going to go into details on &lt;a href="https://docs.microsoft.com/aspnet/core/migration/http-modules?view=aspnetcore-3.0&amp;amp;WT.mc_id=devto-blog-marouill"&gt;how to port HttpModules and Handlers&lt;/a&gt; but let's assume that they are widely different.&lt;/p&gt;

&lt;p&gt;One of the many differences is that &lt;code&gt;HttpModules&lt;/code&gt; could be set within a &lt;code&gt;web.config&lt;/code&gt; file and that config file could be defined at the machine level. That is not possible with Middlewares. At least, not yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does it matter?
&lt;/h2&gt;

&lt;p&gt;So with all those changes, why did it matter for EasyAuth? Well, the application programming model changed quite a lot, and the things that worked with the .NET Framework stopped working with .NET Core.&lt;/p&gt;

&lt;p&gt;I'm sure there's a solution on the way from Microsoft but a client I met encountered the problem, and I wanted to solve the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving the issue
&lt;/h2&gt;

&lt;p&gt;So, after &lt;a href="https://docs.microsoft.com/azure/app-service/overview-authentication-authorization?WT.mc_id=devto-blog-marouill#how-it-works"&gt;understanding how EasyAuth worked&lt;/a&gt;, I've set on to create a &lt;a href="https://github.com/MaximRouiller/MaximeRouiller.Azure.AppService.EasyAuth"&gt;repository&lt;/a&gt; as well as a &lt;a href="https://www.nuget.org/packages/MaximeRouiller.Azure.AppService.EasyAuth/"&gt;NuGet package&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What I was fixed to do was relay the captured identity and claims into the .NET Core authentication pipeline. I'm not doing anything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing the solution
&lt;/h2&gt;

&lt;p&gt;The first step is to install the &lt;a href="https://www.nuget.org/packages/MaximeRouiller.Azure.AppService.EasyAuth/"&gt;NuGet package&lt;/a&gt; using your method of choice. Then, adding an &lt;code&gt;[Authorize(AuthenticationSchemes = "EasyAuth")]&lt;/code&gt; to your controller.&lt;/p&gt;

&lt;p&gt;Finally, adding the following lines of code to your &lt;code&gt;Startup.cs&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;MaximeRouiller.Azure.AppService.EasyAuth&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//... rest of the file&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAuthentication&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;AddEasyAuthAuthentication&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&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;That's it. If your controller has an &lt;code&gt;[Authorize]&lt;/code&gt; attribute, the credentials are going to automatically start populating the &lt;code&gt;User.Identity&lt;/code&gt; of your MVC controller.&lt;/p&gt;

&lt;h2&gt;
  
  
  Question
&lt;/h2&gt;

&lt;p&gt;Should I go farther? Would you like to see this integrated within a supported Microsoft package? Reach out to me directly on &lt;a href="https://twitter.com/MaximRouiller"&gt;Twitter&lt;/a&gt; or the &lt;a href="https://developer.microsoft.com/en-us/advocates/maxime-rouiller"&gt;many other ways available&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>aspnetcore</category>
      <category>azure</category>
      <category>security</category>
    </item>
    <item>
      <title>Solving Cold-Start disturbs serverless' definition and it's okay</title>
      <dc:creator>Maxime Rouiller</dc:creator>
      <pubDate>Wed, 19 Jun 2019 14:50:00 +0000</pubDate>
      <link>https://forem.com/azure/solving-cold-start-disturbs-serverless-definition-and-it-s-okay-1hhn</link>
      <guid>https://forem.com/azure/solving-cold-start-disturbs-serverless-definition-and-it-s-okay-1hhn</guid>
      <description>&lt;p&gt;When you look at Azure Functions, you see it as a great way to achieve elastic scaling of your application. You only pay for what you use, you have a free quota, and they allow you to build entire applications on this model.&lt;/p&gt;

&lt;p&gt;The whole reason why Azure Functions is free is due to its linked plan. It’s called &lt;code&gt;Consumption Plan&lt;/code&gt;. While Azure Functions is an application model, the consumption plan is where the &lt;strong&gt;serverless&lt;/strong&gt; kicks in. You give us your application, and you care less about the servers.&lt;/p&gt;

&lt;p&gt;One of the main selling points of serverless is the ability to scale to 0. It allows you to pay only for what you use and it’s a win-win for everyone involved.&lt;/p&gt;

&lt;p&gt;That would look a little bit like the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WWxE6GFC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.maximerouiller.com/posts/files/premium-functions/001.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WWxE6GFC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.maximerouiller.com/posts/files/premium-functions/001.png" alt="Ideal Scale Behavior"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  About Cold Starts
&lt;/h3&gt;

&lt;p&gt;Cold start happens when an application loads for the first time on a server. What happens behind the scene look as follows.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The cloud receives a request for your application and starts allocating a server for it&lt;/li&gt;
&lt;li&gt;The server downloads your application&lt;/li&gt;
&lt;li&gt;The cloud forwards the request received initially to your application&lt;/li&gt;
&lt;li&gt;The application stacks load up and initialize what it needs to run the code successfully&lt;/li&gt;
&lt;li&gt;Your application loads up and starts handling the request.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This workflow happens every time your application either goes from 0 to 1 or when the cloud scales you out.&lt;/p&gt;

&lt;p&gt;This whole process is essential as Azure can’t keep the servers running all the time without blocking other applications from running on the same servers.&lt;/p&gt;

&lt;p&gt;That time between when the request initially arrives and is handled by a server can be longer than 500ms. What if it takes a few seconds? What do you do to solve that problem?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DClIJswN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.maximerouiller.com/posts/files/premium-functions/002.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DClIJswN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.maximerouiller.com/posts/files/premium-functions/002.png" alt="Scale with cold start"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Premium Functions
&lt;/h3&gt;

&lt;p&gt;Azure Premium Functions is the best way to resolve that problem. It breaks the definition of Serverless by the fact that you can’t scale to 0. It does, however, offer the elastic scale-out that is required to handle a massive amount of load.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v_DaP28f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.maximerouiller.com/posts/files/premium-functions/elastic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v_DaP28f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.maximerouiller.com/posts/files/premium-functions/elastic.png" alt="Elastic Scale-Out"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This minimum of one instance is what makes a night and day difference in terms of improving performance. This single instance already has your application on it; the Azure Functions runtime is ready to handle your application.&lt;/p&gt;

&lt;p&gt;Having a permanent instance removes most of the longer steps needed to handle a request. It effectively removes cold-start issues as seen below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qGNHKulh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.maximerouiller.com/posts/files/premium-functions/003.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qGNHKulh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.maximerouiller.com/posts/files/premium-functions/003.png" alt="Scale with One Pre-Warmed Instance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When would you use Premium Functions? When your application can’t have cold-starts. Not every application require the need for this feature, and I wholeheartedly agree. Keep on using the Consumption Plan if it fits your needs, and the cold-start isn’t a problem.&lt;/p&gt;

&lt;p&gt;If you are among the clients that can’t afford to have cold-start time in your application while still needing the bursting of servers, Premium Function is for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;p&gt;I’ve gone very quickly over the essential feature that I think fixes one of the more significant problems with serverless. More features come with Premium Functions. I’ve left a link to the docs in case you want to read it all by yourself.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/azure/azure-functions/functions-premium-plan?WT.mc_id=devto-blog-marouill#features"&gt;Azure Premium Functions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>azure</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Getting rid of Time Zone issues within Azure Functions</title>
      <dc:creator>Maxime Rouiller</dc:creator>
      <pubDate>Fri, 14 Jun 2019 15:25:00 +0000</pubDate>
      <link>https://forem.com/azure/getting-rid-of-time-zone-issues-within-azure-functions-4066</link>
      <guid>https://forem.com/azure/getting-rid-of-time-zone-issues-within-azure-functions-4066</guid>
      <description>&lt;p&gt;Your client wants to run a database clean up task every day at 2 am. Why? Mostly because it's when there's no traffic on the site and it reduces the amount of risk of someone encountering problems due to maintenance tasks.&lt;/p&gt;

&lt;p&gt;Sounds good! So as an engineer, you know that task is periodic and you don't need to create a Virtual Machine to handle this task. Not even an AppService is required. You can go serverless and benefit from those free million monthly executions that they offer! Wow. Free maintenance tasks!&lt;/p&gt;

&lt;p&gt;You create a new Function app, write some code that looks something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DatabaseCleanUpFunction"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&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;Run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;TimerTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0 0 2 * * *"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="n"&gt;TimerInfo&lt;/span&gt; &lt;span class="n"&gt;myTimer&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="c1"&gt;// todo: clean up the database&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Wow! That was easy! You publish this application to the cloud, test it out manually a few times maybe then publish it to production and head back home.&lt;/p&gt;

&lt;p&gt;When you get back to the office the next day, you realize that the job has run yes... but at 10 pm. Not 2 am. What happened!?&lt;/p&gt;

&lt;p&gt;You've been struck by Time Zones. Oh, that smooth criminal of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Default time zone
&lt;/h2&gt;

&lt;p&gt;The default timezone for Azure Functions is UTC. Since I'm in the Eastern Time Zone, this previous function now runs at 10 pm instead of 2 am. If there were users that were using my application at that time, I could have severely impacted them.&lt;/p&gt;

&lt;p&gt;That is not good.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;There are two ways to go around this. One, we change our trigger's CRON Expression to represent the time in UTC and keep our documentation updated.&lt;/p&gt;

&lt;p&gt;The second way is to tell Azure Functions in which timezone they should interpret the CRON Expression.&lt;/p&gt;

&lt;p&gt;For me, a man of the best Coast, it involves setting the &lt;code&gt;WEBSITE_TIME_ZONE&lt;/code&gt; environment variable to &lt;code&gt;Eastern Standard Time&lt;/code&gt;. If you are on the lesser Coast, you may need to set yours to &lt;code&gt;Pacific Standard Time&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, let's be honest. We're in a global world. You need &lt;a href="https://docs.microsoft.com/previous-versions/windows/it-pro/windows-vista/cc749073(v=ws.10)?WT.mc_id=devto-blog-marouill#time-zones"&gt;The List™&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Find your region on that list, set it in the &lt;code&gt;WEBSITE_TIME_ZONE&lt;/code&gt;, and Azure Function automatically set the correct Time Zone for your CRON expression.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>azure</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Fixing Azure Functions and Azure Storage Emulator 5.8 issue</title>
      <dc:creator>Maxime Rouiller</dc:creator>
      <pubDate>Tue, 19 Mar 2019 13:05:00 +0000</pubDate>
      <link>https://forem.com/maximrouiller/fixing-azure-functions-and-azure-storage-emulator-58-issue-5o4</link>
      <guid>https://forem.com/maximrouiller/fixing-azure-functions-and-azure-storage-emulator-58-issue-5o4</guid>
      <description>&lt;p&gt;So you've updated Azure Functions to the latest version (2.X at the time of writing this), and nothing starts anymore.&lt;/p&gt;

&lt;p&gt;Now, when you boot the Functions host, you get this weird error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[TIMESTAMP] A host error has occurred
[TIMESTAMP] Microsoft.WindowsAzure.Storage: Server encountered an internal error. Please try again after some time.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There happen to be &lt;a href="https://github.com/Azure/azure-functions-host/issues/3795"&gt;an issue opened on GitHub&lt;/a&gt; that relates to Durable Functions and Azure Storage Emulator.&lt;/p&gt;

&lt;p&gt;The thing is, it's not directly related to Azure Durable Functions. It's related, in my opinion, in a breaking change that happened in Azure Storage Emulator 5.8 ways of responding from its API.&lt;/p&gt;

&lt;p&gt;If you want to fix that issue, merge the following setting in your &lt;code&gt;local.settings.json&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;"Values"&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;"AzureWebJobsSecretStorageType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"files"&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This only applies when &lt;code&gt;"AzureWebJobsStorage": "UseDevelopmentStorage=true"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So why should we set that? There was a change that was introduced back in September 2018 when Azure Functions V2 was released. Azure Functions store your secret on disk before 2.0. Azure Functions, when &lt;a href="https://docs.microsoft.com/azure/app-service/deploy-staging-slots?WT.mc_id=devto-blog-marouill#swap-two-slots"&gt;slot swapping environments&lt;/a&gt;, swap the content of the disk including the secrets.&lt;/p&gt;

&lt;p&gt;What this setting does is ensure that Functions stores secrets on your file system by default. It's expected behavior when using a local development environment.&lt;/p&gt;

&lt;p&gt;If you want to read more, there is &lt;a href="https://github.com/Azure/azure-functions-host/wiki/Changes-to-Key-Management-in-Functions-V2"&gt;an entire article on that behavior&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;To fix the issue, you can either use the workaround or &lt;a href="https://docs.microsoft.com/azure/storage/common/storage-use-emulator?WT.mc_id=devto-blog-marouill"&gt;update the Azure Storage Emulator to 5.9&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>serverless</category>
      <category>storage</category>
    </item>
    <item>
      <title>Wrapping Node.js Azure Table Storage API to enable async/await</title>
      <dc:creator>Maxime Rouiller</dc:creator>
      <pubDate>Thu, 14 Mar 2019 19:30:00 +0000</pubDate>
      <link>https://forem.com/maximrouiller/wrapping-nodejs-azure-table-storage-api-to-enable-asyncawait-54c1</link>
      <guid>https://forem.com/maximrouiller/wrapping-nodejs-azure-table-storage-api-to-enable-asyncawait-54c1</guid>
      <description>&lt;p&gt;I love the latest and greatest. Writing code by using the new language syntax is fantastic.&lt;/p&gt;

&lt;p&gt;What happens when your favorite library doesn't? You are stuck trying to find a workaround. We all hate workarounds, but they are the glue that keeps our code together at the end of the day.&lt;/p&gt;

&lt;p&gt;Between the runtime, the frameworks, the libraries, and everything else... we need everyone on the same page.&lt;/p&gt;

&lt;p&gt;Recently, I had to use &lt;a href="http://azure.github.io/azure-storage-node/#toc6__anchor"&gt;Azure Node.js Table Storage API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, let me say &lt;em&gt;I know&lt;/em&gt;. Yes, there is a v10 that exist, and this is the v2. No, &lt;a href="https://github.com/Azure/azure-storage-js#azure-storage-sdk-v10-for-javascript"&gt;v10 doesn't support Table Storage yet&lt;/a&gt;. So, let's move on.&lt;/p&gt;

&lt;p&gt;Here's the code I wanted to see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;azure-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getAllFromTable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;tableService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createTableService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TableQuery&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PartitionKey eq ?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultPartitionKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;queryEntities&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tableService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TableName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&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;Here's the code that I had:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getAllFromTable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;tableService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createTableService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TableQuery&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PartitionKey eq ?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultPartitionKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;tableService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryEntities&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TableName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&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="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;The sight of function callbacks gave me flashbacks to a time where code indentation warranted wider monitors.&lt;/p&gt;

&lt;h2&gt;
  
  
  The workaround
&lt;/h2&gt;

&lt;p&gt;Here's the temporary workaround that I have for now. It allows me to wrap highly used functions into something more straightforward.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;queryEntities&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tableService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;promiseHandling&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&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="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promiseHandling&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;tableService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryEntities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tableService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&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;h3&gt;
  
  
  Overview of the workaround
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;We're using async everywhere&lt;/li&gt;
&lt;li&gt;Using Rest parameters &lt;code&gt;args&lt;/code&gt; allow us to trap all parameters from that API&lt;/li&gt;
&lt;li&gt;We're wrapping the proper promise and inserting it into the arguments&lt;/li&gt;
&lt;li&gt;We're calling the relevant API with the proper argument.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;That's it. While the Node.js Storage v10 is having table storage implemented, I recommend wrapping table storage code into a similar structure.&lt;/p&gt;

&lt;p&gt;This will allow you to use the new language syntax while they update the library.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>node</category>
      <category>storage</category>
    </item>
    <item>
      <title>How to build a multistage Dockerfile for SPA and static sites</title>
      <dc:creator>Maxime Rouiller</dc:creator>
      <pubDate>Thu, 21 Feb 2019 19:00:00 +0000</pubDate>
      <link>https://forem.com/maximrouiller/how-to-build-a-multistage-dockerfile-for-spa-and-static-sites-1cck</link>
      <guid>https://forem.com/maximrouiller/how-to-build-a-multistage-dockerfile-for-spa-and-static-sites-1cck</guid>
      <description>&lt;p&gt;When you are a consultant, your goal is to think about the best way to save money for your client. They are not paying us because we can code. They are paying because we can remove a few dollars (or a few hundred) from their bills.&lt;/p&gt;

&lt;p&gt;One of the situations we often find ourselves in is building a single page application (SPA). Clients want dynamically driven applications that don't refresh the whole page, and a SPA is often the perfect choice for them. Among the many tools used to build a SPA, we find Angular, Vue, and React.&lt;/p&gt;

&lt;p&gt;I've found that delivering websites with containers is a universal way of ensuring compatibility across environments, cloud or not. It also prevents a developer's environment from having to install 25 different tools/languages/SDKs.&lt;/p&gt;

&lt;p&gt;It keeps thing concise and efficient.&lt;/p&gt;

&lt;p&gt;If you want to &lt;a href="https://docs.microsoft.com/dotnet/standard/containerized-lifecycle-architecture/what-is-docker?WT.mc_id=maximerouiller-blog-marouill"&gt;know more about Docker containers&lt;/a&gt;, take a few minutes, in particular, to read about &lt;a href="https://docs.microsoft.com/dotnet/standard/containerized-lifecycle-architecture/docker-terminology?WT.mc_id=maximerouiller-blog-marouill"&gt;the terminology&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The problem is that we only need Node.js to build that application, not to run it. So, how would containers solve our problem? There's a concept in Docker called &lt;a href="https://docs.docker.com/develop/develop-images/multistage-build/"&gt;Multistage builds&lt;/a&gt; where you can separate the build process from the execution.&lt;/p&gt;

&lt;p&gt;Here’s a template you can use to build a SPA with Node.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dockerfile template for Node.js
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: this is a template taken from the VueJS documentation.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;#build stage for a Node.js application&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:lts-alpine as build-stage&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="c"&gt;#production stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx:stable-alpine as production-stage&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build-stage /app/dist /usr/share/nginx/html&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 80&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["nginx", "-g", "daemon off;"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There's a lot to unpack here. Let's look at the two stages separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Stage (Node.js)
&lt;/h2&gt;

&lt;p&gt;Multistage docker builds allow us to split our container in two ways. Let's look at the build stage.&lt;/p&gt;

&lt;p&gt;The first line is a classic. We're starting from an Alpine image that has Node.js pre-installed on it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Alpine Linux is a security-oriented, lightweight Linux distribution based on musl libc and busybox. Its main characteristic is it runs everywhere and is extremely small, around 5MB.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We're configuring &lt;code&gt;/app&lt;/code&gt; as the working directory. Then, we do something unusual. We copy our &lt;code&gt;package*.json&lt;/code&gt; files before copying everything else.&lt;/p&gt;

&lt;p&gt;Why? Each line in a Dockerfile represents a layer. When building a layer, if a layer already exists locally, is retrieved from the cache instead of being rebuilt. By copying and installing our packages in a separate step, we avoid running &lt;code&gt;npm install&lt;/code&gt; on dependencies that didn't change in the first place. Since &lt;code&gt;npm install&lt;/code&gt; can take a while to install, we save some time there.&lt;/p&gt;

&lt;p&gt;Finally, we copy the rest of our app and run the npm &lt;code&gt;build&lt;/code&gt; task. If your application doesn't have a &lt;code&gt;build&lt;/code&gt; task, change the name to whatever tasks generate an output folder like &lt;code&gt;dist&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The result? We have a correctly built Node.js application located in &lt;code&gt;/app/dist&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Stage
&lt;/h2&gt;

&lt;p&gt;We've generated our SPA or static site with Node.js but... our application isn't using Node.js. It's using HTML/CSS/JS. We don't need a Node.js image to take our application to production. Instead, we only need an HTTP server. Let's use the &lt;a href="https://hub.docker.com/_/nginx"&gt;NGINX Docker Image&lt;/a&gt; as a host.&lt;/p&gt;

&lt;p&gt;We copy the output from our previously defined &lt;code&gt;build-stage&lt;/code&gt; &lt;code&gt;/app/dist&lt;/code&gt; folder into the NGINX defined folder &lt;code&gt;/usr/share/nginx/html&lt;/code&gt; as &lt;a href="https://github.com/docker-library/docs/tree/master/nginx#how-to-use-this-image"&gt;mentioned in their docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After exposing port 80, we need to run NGINX with the &lt;code&gt;daemon off;&lt;/code&gt; option to have it run in the foreground and preventing the container from closing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Dockerfile
&lt;/h2&gt;

&lt;p&gt;This step is easy. Run the following command in the folder containing the &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; mydockerapp:latest &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Running the Docker container locally
&lt;/h2&gt;

&lt;p&gt;Running the application on your machine is of course just a simple command away.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 mydockerapp:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This command is doing two things. First, it runs the container in interactive mode with the &lt;code&gt;-i&lt;/code&gt; flag. That flag will allow us to see the output of NGINX as it runs. Second, it maps port 8080 of your local machine to port 80 of the container.&lt;/p&gt;

&lt;p&gt;Opening your browser to &lt;code&gt;http://localhost:8080&lt;/code&gt; will show you your website.&lt;/p&gt;

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

&lt;p&gt;I'm using Docker more and more for everything. I'm building applications that are single use with current technology. Docker empowers me in running applications with older versions of frameworks, runtime, languages, without causing tooling versioning issue with my machine.&lt;/p&gt;

&lt;p&gt;While technology may continue to evolve, I'm never afraid that my Docker container won't work anymore. Things have been stuck in time if only for a moment.&lt;/p&gt;

&lt;p&gt;That means I don't have to upgrade that AngularJS 1.X app to stay cool. If it works, it works.&lt;/p&gt;

&lt;p&gt;Are you using Docker in unusual ways? Share them with me &lt;a href="https://twitter.com/MaximRouiller"&gt;on Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>webdev</category>
      <category>node</category>
      <category>static</category>
    </item>
  </channel>
</rss>
