<?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: Thiago Custódio</title>
    <description>The latest articles on Forem by Thiago Custódio (@thdotnet).</description>
    <link>https://forem.com/thdotnet</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%2F228701%2F56c68a2e-589b-40b9-8a56-eb3ef52c8f8a.jpg</url>
      <title>Forem: Thiago Custódio</title>
      <link>https://forem.com/thdotnet</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/thdotnet"/>
    <language>en</language>
    <item>
      <title>Azure Landing Zones and CAF: A Strategic Roadmap to Cloud Success</title>
      <dc:creator>Thiago Custódio</dc:creator>
      <pubDate>Thu, 14 Mar 2024 15:01:22 +0000</pubDate>
      <link>https://forem.com/thdotnet/azure-landing-zones-and-caf-a-strategic-roadmap-to-cloud-success-3860</link>
      <guid>https://forem.com/thdotnet/azure-landing-zones-and-caf-a-strategic-roadmap-to-cloud-success-3860</guid>
      <description>&lt;p&gt;In the past, I had heard a lot about the Cloud Adoption Framework and its benefits. Then, people began promoting Azure Landing Zones, but the relationship between them wasn't clear to me.&lt;/p&gt;

&lt;p&gt;The Cloud Adoption Framework (CAF) is a comprehensive playbook designed to facilitate a seamless transition to the cloud. It encompasses everything from initial planning and readiness assessment to the actual migration, security, governance, and ongoing optimization.&lt;/p&gt;

&lt;p&gt;Landing Zones are pre-configured environments that serve as a secure foundation for cloud deployments. The principles of the CAF are embodied in Azure Landing Zones, providing a scalable, compliant, and secure starting point for your cloud journey.&lt;/p&gt;

&lt;p&gt;In summary, Landing Zones and the Cloud Adoption Framework are complementary, with the CAF providing the comprehensive strategy and best practices for cloud adoption, and Landing Zones offering the practical, technical foundation that aligns with the CAF's guidelines.&lt;/p&gt;

&lt;p&gt;Seeking Expertise? If you're looking for guidance or wish to deepen your understanding of Azure Landing Zones and the CAF, let's connect. Together, we can explore how these powerful tools can be tailored to fit your organization's unique needs, driving your cloud adoption towards success with precision and confidence.&lt;/p&gt;

&lt;h1&gt;
  
  
  azure #cloud #microsoft #mvp #CloudWithThiago #DigitalTransformation #CloudAdoptionFramework #landingzone #AzureLandingZone
&lt;/h1&gt;

</description>
      <category>azure</category>
      <category>caf</category>
      <category>landingzone</category>
    </item>
    <item>
      <title>The 5 Disciplines of Cloud Governance</title>
      <dc:creator>Thiago Custódio</dc:creator>
      <pubDate>Fri, 08 Mar 2024 20:14:16 +0000</pubDate>
      <link>https://forem.com/thdotnet/the-5-disciplines-of-cloud-governance-29f9</link>
      <guid>https://forem.com/thdotnet/the-5-disciplines-of-cloud-governance-29f9</guid>
      <description>&lt;p&gt;Governance refers to the mechanisms, processes, and relations by which an organization is controlled and directed. It encapsulates the framework within which objectives are set and the means of attaining those objectives and monitoring performance are determined. &lt;/p&gt;

&lt;p&gt;Why Establish Governance Over Your Cloud Environment?&lt;br&gt;
In the rapidly evolving landscape of cloud technology, establishing a governance framework is imperative. It ensures that the use of cloud services aligns with an organization's strategic goals, complies with regulatory requirements, and optimizes resource utilization. &lt;/p&gt;

&lt;p&gt;Without effective governance, organizations may face uncontrolled cloud costs, security vulnerabilities, inconsistent resource management, and challenges in scaling operations efficiently. Governance provides a structured approach to managing these complexities, ensuring that cloud services contribute positively to the organizational objectives.&lt;/p&gt;

&lt;p&gt;Key Disciplines of Cloud Governance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cost Management: Cost management within cloud governance involves monitoring and controlling spending to avoid overutilization or underutilization of resources. This discipline ensures that organizations can forecast their spending accurately and allocate their cloud budget efficiently, maximizing the return on investment in cloud services. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security Baseline: Establishing a security baseline is critical in defining the minimum-security standards for protecting cloud resources. This includes implementing policies for access control, data encryption, and threat detection to mitigate risks and comply with data protection regulations. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resource Consistency: Resource consistency aims to standardize the configuration and management of cloud resources. By ensuring a uniform approach across the cloud environment, organizations can streamline operations, reduce errors, and improve the reliability of their services. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identity Baseline: The identity baseline discipline focuses on managing user identities and access privileges. It is essential for defining who can access specific cloud resources and what actions they are authorized to perform, thereby safeguarding sensitive data and systems from unauthorized use. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deployment Acceleration: Deployment acceleration refers to the practices and tools that enable organizations to launch and update cloud services more rapidly and efficiently. This discipline supports agility and innovation by reducing the time to market for new features and applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Establishing cloud governance is a critical strategic framework that enables organizations to leverage cloud computing effectively and responsibly. By adhering to these disciplines, organizations can achieve operational excellence, enhance security, and drive innovation in their cloud environments.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>cloudcomputing</category>
      <category>governance</category>
    </item>
    <item>
      <title>Quick tip on Azure Cosmos DB indexes</title>
      <dc:creator>Thiago Custódio</dc:creator>
      <pubDate>Wed, 21 Feb 2024 16:30:19 +0000</pubDate>
      <link>https://forem.com/thdotnet/quick-tip-on-azure-cosmos-db-indexes-44l6</link>
      <guid>https://forem.com/thdotnet/quick-tip-on-azure-cosmos-db-indexes-44l6</guid>
      <description>&lt;p&gt;"Don't accept the defaults." - Abel Wang&lt;/p&gt;

&lt;p&gt;Most people aren't aware, but by default, every property in your document stored in Cosmos DB is indexed. While this is fantastic for performance, optimizing query speed across your data, it can become costly if you're dealing with a large amount of data. &lt;/p&gt;

&lt;p&gt;This default behavior, though beneficial in many scenarios, may not suit every use case, especially when budget constraints are tight, or specific data doesn't require fast query access.&lt;/p&gt;

&lt;p&gt;The good news is that Azure Cosmos DB offers the flexibility to customize this behavior. You have the option to disable indexing on certain properties or to create custom indexes that better fit your application's needs, potentially saving costs without compromising on performance where it matters most.&lt;/p&gt;

&lt;p&gt;For those looking to dive deeper into how to fine-tune your Azure Cosmos DB setup, Microsoft Learn offers a comprehensive guide on customizing indexes for the SQL API. It covers everything from the basics of indexing to advanced techniques for optimizing your data access patterns.&lt;/p&gt;

&lt;p&gt;Learn how to optimize your Azure Cosmos DB indexes: &lt;a href="https://learn.microsoft.com/en-us/training/modules/customize-indexes-azure-cosmos-db-sql-api/2-customize-indexing-policy"&gt;Customize Indexes in Azure Cosmos DB for the SQL API.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Taking control of your database's indexing strategy can lead to significant performance improvements and cost savings. Don't settle for the defaults; tailor your Azure Cosmos DB to meet your specific needs.&lt;/p&gt;

&lt;h1&gt;
  
  
  azure #cosmosDb #microsoft #cloud #CloudWithThiago #AzureTips
&lt;/h1&gt;

</description>
      <category>azure</category>
      <category>cosmosdb</category>
      <category>cloudcomputing</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>Quick tip on Azure Cosmos DB indexes</title>
      <dc:creator>Thiago Custódio</dc:creator>
      <pubDate>Wed, 21 Feb 2024 16:30:17 +0000</pubDate>
      <link>https://forem.com/thdotnet/quick-tip-on-azure-cosmos-db-indexes-2ilb</link>
      <guid>https://forem.com/thdotnet/quick-tip-on-azure-cosmos-db-indexes-2ilb</guid>
      <description>&lt;p&gt;"Don't accept the defaults." - Abel Wang&lt;/p&gt;

&lt;p&gt;Most people aren't aware, but by default, every property in your document stored in Cosmos DB is indexed. While this is fantastic for performance, optimizing query speed across your data, it can become costly if you're dealing with a large amount of data. &lt;/p&gt;

&lt;p&gt;This default behavior, though beneficial in many scenarios, may not suit every use case, especially when budget constraints are tight, or specific data doesn't require fast query access.&lt;/p&gt;

&lt;p&gt;The good news is that Azure Cosmos DB offers the flexibility to customize this behavior. You have the option to disable indexing on certain properties or to create custom indexes that better fit your application's needs, potentially saving costs without compromising on performance where it matters most.&lt;/p&gt;

&lt;p&gt;For those looking to dive deeper into how to fine-tune your Azure Cosmos DB setup, Microsoft Learn offers a comprehensive guide on customizing indexes for the SQL API. It covers everything from the basics of indexing to advanced techniques for optimizing your data access patterns.&lt;/p&gt;

&lt;p&gt;Learn how to optimize your Azure Cosmos DB indexes: &lt;a href="https://learn.microsoft.com/en-us/training/modules/customize-indexes-azure-cosmos-db-sql-api/2-customize-indexing-policy"&gt;Customize Indexes in Azure Cosmos DB for the SQL API.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Taking control of your database's indexing strategy can lead to significant performance improvements and cost savings. Don't settle for the defaults; tailor your Azure Cosmos DB to meet your specific needs.&lt;/p&gt;

&lt;h1&gt;
  
  
  azure #cosmosDb #microsoft #cloud #CloudWithThiago #AzureTips
&lt;/h1&gt;

</description>
      <category>azure</category>
      <category>cosmosdb</category>
      <category>cloudcomputing</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>How Azure Container Apps Simplify the Cloud Deployment Process</title>
      <dc:creator>Thiago Custódio</dc:creator>
      <pubDate>Mon, 12 Feb 2024 17:25:17 +0000</pubDate>
      <link>https://forem.com/thdotnet/how-azure-container-apps-simplify-the-cloud-deployment-process-29dn</link>
      <guid>https://forem.com/thdotnet/how-azure-container-apps-simplify-the-cloud-deployment-process-29dn</guid>
      <description>&lt;p&gt;In the recent past, while supporting one of our clients through their digital transformation journey, they shared the decision to adopt Kubernetes as their preferred platform for container orchestration. During the assessment phase, where we gather more information about the client, the project, and internal processes, several questions emerged:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How familiar are you with the Kubernetes ecosystem and its components?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have you faced any challenges in configuring networking between microservices within Kubernetes? If so, how have you addressed them?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do you manage the lifecycle of your applications within Kubernetes, from deployment to scaling to updates?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It became clear to me that Kubernetes was their goal for a container orchestration platform, but at that moment, they were not ready for it. More than that, they were unaware of the challenges and the processes they would need to adopt in order to succeed (I will write more about this in another post).&lt;/p&gt;

&lt;p&gt;Continue reading on: &lt;a href="https://lnkd.in/ge8F8UHQ"&gt;https://lnkd.in/ge8F8UHQ&lt;/a&gt; &lt;/p&gt;

</description>
      <category>azure</category>
      <category>kubernetes</category>
      <category>containerapps</category>
    </item>
    <item>
      <title>My highlights from Microsoft Build 2023 for Azure Functions</title>
      <dc:creator>Thiago Custódio</dc:creator>
      <pubDate>Wed, 24 May 2023 16:54:43 +0000</pubDate>
      <link>https://forem.com/thdotnet/my-highlights-from-microsoft-build-2023-for-azure-functions-ef2</link>
      <guid>https://forem.com/thdotnet/my-highlights-from-microsoft-build-2023-for-azure-functions-ef2</guid>
      <description>&lt;p&gt;Microsoft Build 2023 brought exciting new developments for Azure Functions, empowering developers to create powerful serverless applications with ease. In this blog post, we will dive into the top three highlights from the event that will transform the way you leverage Azure Functions. From enhanced data integration to automated triggers and a revolutionary storage backend, these updates are set to take your applications to new heights.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure SQL Bindings: Seamless Integration for Data Access and Manipulation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Azure SQL bindings for Azure Functions have officially become generally available, marking a significant milestone in the evolution of serverless computing. This development enables effortless integration between Azure SQL and your Functions, allowing for seamless data access and manipulation. With this feature, you can now build applications that interact with Azure SQL databases without the need for complex configurations or extensive coding efforts. By simplifying the data integration process, Azure Functions empower developers to focus on application logic and deliver robust solutions more efficiently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure Cache for Redis Trigger: Automate Actions with Real-time Redis Cache Monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Introducing the Azure Cache for Redis trigger, a game-changer in the world of serverless computing. This powerful feature allows developers to react to changes in their Redis cache and trigger Azure Functions accordingly. Gone are the days of manual monitoring and continuous polling. With this trigger, you can automate actions based on real-time updates in your Redis cache, significantly improving efficiency and responsiveness. Whether it's updating related data, processing notifications, or executing custom business logic, the Azure Cache for Redis trigger simplifies the development process by providing a seamless integration point between your Redis cache and Azure Functions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft Netherite &amp;amp; MSSQL: Revolutionary Storage Backend for Durable Functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hold your breath for the most revolutionary update yet! Microsoft Build 2023 introduced a cutting-edge storage backend for Durable Functions called Microsoft Netherite &amp;amp; MSSQL. This breakthrough technology takes Durable Functions to the next level, providing enhanced performance and scalability. With Netherite &amp;amp; MSSQL, you can achieve unprecedented levels of efficiency when managing long-running workflows and stateful orchestrations. Leveraging the power of Microsoft SQL Server, this storage backend offers robust durability, fault tolerance, and global scalability, ensuring your Durable Functions can handle the most demanding workloads with ease. &lt;/p&gt;

&lt;p&gt;The highlights from Microsoft Build 2023 for Azure Functions showcased the continuous innovation happening in the serverless computing space. The availability of Azure SQL bindings simplifies data integration, the Azure Cache for Redis trigger automates actions with real-time updates, and the introduction of Microsoft Netherite &amp;amp; MSSQL brings a revolutionary storage backend to Durable Functions. These updates empower developers to build more efficient, scalable, and responsive applications, ultimately driving greater value and delivering exceptional user experiences. &lt;/p&gt;

&lt;p&gt;Stay tuned for more exciting developments as Azure Functions continues to evolve and revolutionize the world of serverless computing. &lt;/p&gt;

&lt;p&gt;For more information: &lt;a href="https://techcommunity.microsoft.com/t5/apps-on-azure-blog/azure-functions-may-update-for-microsoft-build/ba-p/3827388"&gt;https://techcommunity.microsoft.com/t5/apps-on-azure-blog/azure-functions-may-update-for-microsoft-build/ba-p/3827388&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>azurefunctions</category>
      <category>serverless</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>The Well Architected Framework</title>
      <dc:creator>Thiago Custódio</dc:creator>
      <pubDate>Thu, 15 Dec 2022 14:17:31 +0000</pubDate>
      <link>https://forem.com/thdotnet/the-well-architected-framework-3min</link>
      <guid>https://forem.com/thdotnet/the-well-architected-framework-3min</guid>
      <description>&lt;p&gt;The Well Architected Framework is a set of guidelines and best practices for building good cloud computing applications.&lt;/p&gt;

&lt;p&gt;It can help you make sure your applications are reliable, secure, efficient, and cost-effective. Some of the benefits of using the Well Architected Framework include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Better performance: The framework can help you design your applications so they run faster and more smoothly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improved security: The framework includes guidelines for protecting your applications from cyber threats and unauthorized access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduced costs: The framework can help you save money by making sure you only use the resources you need, and by helping you avoid costly mistakes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Greater scalability: The framework can help you design your applications so they can easily handle increases in traffic or data without breaking.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, the Well Architected Framework is a helpful tool for anyone who wants to build high-quality, successful cloud computing applications.&lt;/p&gt;

&lt;p&gt;Do you want to learn more about it?&lt;br&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/azure/architecture/framework/"&gt;https://learn.microsoft.com/en-us/azure/architecture/framework/&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  azure #microsoft #cloud #cloudcomputing #wellArchitectedFramework
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>Rompendo barreiras com tradutor multi idiomas</title>
      <dc:creator>Thiago Custódio</dc:creator>
      <pubDate>Sat, 16 Nov 2019 19:28:49 +0000</pubDate>
      <link>https://forem.com/thdotnet/rompendo-barreiras-com-tradutor-multi-idiomas-3c3i</link>
      <guid>https://forem.com/thdotnet/rompendo-barreiras-com-tradutor-multi-idiomas-3c3i</guid>
      <description>&lt;p&gt;Outro dia, esse tweet apareceu na minha linha do tempo do Twitter:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GztXM_mw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xadpcqupjglxba4xarth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GztXM_mw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xadpcqupjglxba4xarth.png" alt="Polemic tweet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Meio extremo, mas eu entendi o ponto de vista dele, apesar de acreditar que as pessoas são livres para postar o que quiserem e no idioma que desejam. Como você pode ver, muitas pessoas responderam a esse tweet e ele se tornou um tópico interessante.&lt;/p&gt;

&lt;p&gt;Às vezes, o que você deseja compartilhar é relevante para parte do seu público, outras vezes pode ser útil para várias culturas e, como o inglês é o idioma universal, acredito que devemos compartilhar o conteúdo em inglês.&lt;/p&gt;

&lt;p&gt;"Mas eu não falo inglês, o que posso fazer?"&lt;/p&gt;

&lt;p&gt;Acredite ou não, existe um site que pode traduzir o que você deseja para vários idiomas e é gratuito. Tudo o que você precisa fazer é acessar &lt;a href="https://translate.google.com"&gt;https://translate.google.com&lt;/a&gt; e selecionar os idiomas de origem e de destino, escrever o texto que deseja traduzir e pressionar a tecla Enter.&lt;/p&gt;

&lt;p&gt;WOW!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;História engraçada: meu amigo Rodrigo Kono viajou para o Japão e passou duas horas no aeroporto tentando obter ajuda para ir ao hotel. Ele me enviou um áudio dizendo esse "problema" e lembrei-o do aplicativo tradutor do Google, que possui um recurso em que você pode usar a câmera do seu telefone para traduzir um texto em tempo real. Ele conseguiu ir para o hotel e dias depois, retornar ao Brasil e o dia foi salvo graças ao seu antigo colega de quarto aqui.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mas e se você não é um fã do Google ou se deseja incluir recursos de tradução em seus aplicativos? Você pode consumir modelos pré-treinados de IA por meio de APIs REST e obter o mesmo resultado.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Em 2016, enquanto eu morava na Nova Zelândia, conheci um cara que começou sua própria empresa depois que seu aplicativo foi apresentado no Tech Crunch. Basicamente, ele criou um aplicativo disruptivo de tradução de 1-N idiomas. Você pode ler o artigo completo aqui: &lt;a href="https://techcrunch.com/2016/04/20/miss-d-is-a-dictionary-app-for-the-linguistically-curious/"&gt;https://techcrunch.com/2016/04/20/miss-d-is-a-dictionary-app-for-the-linguistically-curious/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Codificando seu próprio mecanismo de tradução usando o Cognitive Services + Azure Functions + Azure Storage
&lt;/h2&gt;

&lt;p&gt;A primeira coisa que precisamos fazer é acessar o Portal do Azure e criar um novo "Texto do Tradutor" na sua Assinatura do Azure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b2u6mlAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2crp38w7ulqlzhcau3hj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b2u6mlAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2crp38w7ulqlzhcau3hj.png" alt="Criando um tradutor de serviço cognitivo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em seguida, precisamos escolher a camada de preços e escolher um nome para o serviço:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ez0l-9wm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vcy7orzktlwrty9kbe0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ez0l-9wm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vcy7orzktlwrty9kbe0y.png" alt="Especificando o nome e o grupo de recursos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora, vamos criar um projeto do Azure Functions usando o Visual Studio:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lxjmzzi7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/esb5werv9x1lxayscmej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lxjmzzi7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/esb5werv9x1lxayscmej.png" alt="Criando um novo projeto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois disso, vamos especificar que nossa função será acionada sempre que um novo blob for carregado na nossa conta de armazenamento:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qTL07DsM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7h82841pslj1uqp2ikpm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qTL07DsM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7h82841pslj1uqp2ikpm.png" alt="Selecionando o tipo de gatilho para a Função Azure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em seguida, precisamos instalar um pacote nuget para simplificar a requisição http ao Serviço Cognitivo, que traduzirá o texto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using CognitiveServices.Translator;
using CognitiveServices.Translator.Translate;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Azure.Storage.Auth;

namespace MultiLanguageTranslator
{
    public class Function1
    {
        [FunctionName("Function1")]
        public static void Run([BlobTrigger("english/{name}", Connection = "StorageConnectionString")]Stream myBlob, string name, ILogger log)
        {
            log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");

            var translateClient = new TranslateClient(new CognitiveServices.Translator.Configuration.CognitiveServicesConfig
            {
                Name = Environment.GetEnvironmentVariable("CognitiveServicesName"),
                SubscriptionKey = Environment.GetEnvironmentVariable("CognitiveServicesKey"),
                SubscriptionKeyAlternate = Environment.GetEnvironmentVariable("CognitiveServicesKey"),
            });

            using (var sr = new StreamReader(myBlob))
            {
                var fullContent = sr.ReadToEnd();
                var desiredLanguages = new string[] { "de", "es", "fr", "pt",  "it", "nl" };

                var responses = translateClient.Translate(new RequestContent(fullContent), new RequestParameter
                {
                    From = "en",
                    To = desiredLanguages,
                    IncludeAlignment = true
                });

                var storageAccountName = Environment.GetEnvironmentVariable("StorageAccountName");
                var storageAccountKey = Environment.GetEnvironmentVariable("StorageAccountKey");
                var storageAccountEndpoint = Environment.GetEnvironmentVariable("StorageEndpoint");

                var storageCredentials = new StorageCredentials(accountName: storageAccountName, keyValue: storageAccountKey);
                var blobClient = new CloudBlobClient(new Uri(storageAccountEndpoint), storageCredentials);

                var container = blobClient.GetContainerReference("translations");
                container.CreateIfNotExists();

                foreach (var response in responses)
                {
                    foreach(var translation in response.Translations)
                    {
                        var blob = container.GetBlockBlobReference($"{translation.To}.txt");
                        blob.UploadText(translation.Text);
                    }
                }
            }
        }
    }
}


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Em resumo, o Azure Functions obterá o conteúdo do texto original que será carregado na Conta de Armazenamento definida por meio da string de conexão StorageConnectionString. O conteúdo pode ser acessado através da variável &lt;code&gt;myBlob&lt;/code&gt;.&lt;br&gt;
Estamos lendo o conteúdo usando a classe StreamReader e, em seguida, criando um array de strings com os idiomas que queremos traduzir a partir do conteúdo original em inglês.&lt;/p&gt;

&lt;p&gt;Em seguida, obtemos algumas variáveis de ambiente (definiremos no Portal do Azure quando criarmos a Azure Function) e finalmente, vamos acessar a conta de armazenamento mais uma vez para armazenar o texto traduzido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hospedando o código criado
&lt;/h2&gt;

&lt;p&gt;Primeiro, vamos criar a conta de armazenamento:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bs1b1Bgk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/o398yk9oeaygtejljyrl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bs1b1Bgk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/o398yk9oeaygtejljyrl.png" alt="Criando uma conta de armazenamento"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9DLRwIpV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2q2r82cblxz9sbzvkz66.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9DLRwIpV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2q2r82cblxz9sbzvkz66.png" alt="Criando uma conta de armazenamento parte 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em seguida, vamos criar a Azure Function e obter o perfil de publicação para simplificar nosso processo de publicação:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xiZYHSP7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5lafm4rrip49ebomgw5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xiZYHSP7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5lafm4rrip49ebomgw5b.png" alt="Criando uma Azure Function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vmiA_ZwQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wna2uqyzs46f6eu8n4vu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vmiA_ZwQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wna2uqyzs46f6eu8n4vu.png" alt="Criando uma Azure Function 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois de pronto, podemos obter o perfil de publicação na aba Visão geral:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pmu6wEM4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/btrz16hmix03xv51kdiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pmu6wEM4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/btrz16hmix03xv51kdiw.png" alt="Obtendo o perfil de publicação"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora, vamos usar nosso Visual Studio para publicar nosso código:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--71mbIQxG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/h0wetsoamoxpro07d2uh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--71mbIQxG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/h0wetsoamoxpro07d2uh.png" alt="Publicando o projeto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por fim, vamos criar as variáveis de ambiente clicando no link de configuração também fica na aba Visão geral:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lcoTPuI---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/p6pkrawwsjtwpw5iwjjv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lcoTPuI---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/p6pkrawwsjtwpw5iwjjv.gif" alt="Criando variáveis de ambiente"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos ver tudo em ação:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zew4XQQL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/c2i2r3po51tepcoetju9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zew4XQQL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/c2i2r3po51tepcoetju9.gif" alt="Testando a nossa aplicação"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A lista completa de idiomas suportados pode ser encontrada aqui: &lt;a href="https://docs.microsoft.com/en-us/azure/cognitive-services/translator/language-support"&gt;https://docs.microsoft.com/en-us/azure/cognitive-services/translator/language-support&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>csharp</category>
      <category>azurefunctions</category>
      <category>cognitiveservices</category>
    </item>
    <item>
      <title>Breaking the barriers with a multi language translator</title>
      <dc:creator>Thiago Custódio</dc:creator>
      <pubDate>Sat, 16 Nov 2019 19:09:25 +0000</pubDate>
      <link>https://forem.com/thdotnet/breaking-the-barriers-with-a-multi-language-translator-53cg</link>
      <guid>https://forem.com/thdotnet/breaking-the-barriers-with-a-multi-language-translator-53cg</guid>
      <description>&lt;p&gt;Another day this tweet appeared on my Twitter timeline:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GztXM_mw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xadpcqupjglxba4xarth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GztXM_mw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xadpcqupjglxba4xarth.png" alt="Polemic tweet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;English: "IT Brazilians professionals who lives in Brazil, with no real relevance overseas, tweeting in English, until when?&lt;br&gt;
Our country needs good professionals, and needs to include hundred thousands of people in IT, and most of them don't speak English. Be better than that, share in Portuguese.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kind of extreme, but I understood his point even though I believe people is free to post whatever they want and in the language they want. As you can see, many people had replied to this tweet and it became an interesting thread.&lt;/p&gt;

&lt;p&gt;Sometimes what you want to share is relevant to part of your audience, other times it can be useful to multiple cultures and as English is the universal language, I do believe we should share the content in English.&lt;/p&gt;

&lt;p&gt;"But I don't speak English, what can I do?"&lt;/p&gt;

&lt;p&gt;Believe or not, there's a website who can translate what you want to multiple languages, and it's free. All you need to do is go to &lt;a href="https://translate.google.com"&gt;https://translate.google.com&lt;/a&gt; and select the source and target languages, write the text you want to translate and hit the enter key.&lt;/p&gt;

&lt;p&gt;WOW!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Funny story: my friend Rodrigo Kono traveled to Japan and spent two hours at the airport trying to get help to go to his hotel. He sent me an audio telling me this "problem" and I reminded him about Google translator app, which has a feature where you can use the camera of your phone to translate a text in real time. He managed to go to his hotel and days later, return to Brazil and the day was salved thanks to his former roommate over here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But what if you're not a Google fan or if you want to include translation features in your applications? You can consume AI pre-trained models through REST API's and achieve the same result.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In 2016 while I was living in New Zealand, I've met a guy who started his own company after his app got featured on Tech Crunch. Basically he created an app and disrupted the traditional 1-1 language translation. You can read the full article in here: &lt;a href="https://techcrunch.com/2016/04/20/miss-d-is-a-dictionary-app-for-the-linguistically-curious/"&gt;https://techcrunch.com/2016/04/20/miss-d-is-a-dictionary-app-for-the-linguistically-curious/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Coding your own translation mechanism using Cognitive Services + Azure
&lt;/h2&gt;

&lt;p&gt;Functions + Azure Storage&lt;/p&gt;

&lt;p&gt;The first thing we need to do is access Azure Portal and create a new "Translator Text" in your Azure Subscription:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b2u6mlAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2crp38w7ulqlzhcau3hj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b2u6mlAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2crp38w7ulqlzhcau3hj.png" alt="Creating a Cognitive Service Translator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we need to choose the pricing tier and choose a name for the service&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ez0l-9wm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vcy7orzktlwrty9kbe0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ez0l-9wm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vcy7orzktlwrty9kbe0y.png" alt="Specifying the name and resource group"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's create an Azure Functions project using Visual Studio:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lxjmzzi7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/esb5werv9x1lxayscmej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lxjmzzi7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/esb5werv9x1lxayscmej.png" alt="Creating a new project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, let's specify that our function will be triggered whenever a new blob was uploaded to our Storage Account:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qTL07DsM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7h82841pslj1uqp2ikpm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qTL07DsM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7h82841pslj1uqp2ikpm.png" alt="Selecting the trigger type for the Azure Function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next we need to install a nuget package to simplify the http request against the Cognitive Service which will translate out text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using CognitiveServices.Translator;
using CognitiveServices.Translator.Translate;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Azure.Storage.Auth;

namespace MultiLanguageTranslator
{
    public class Function1
    {
        [FunctionName("Function1")]
        public static void Run([BlobTrigger("english/{name}", Connection = "StorageConnectionString")]Stream myBlob, string name, ILogger log)
        {
            log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");

            var translateClient = new TranslateClient(new CognitiveServices.Translator.Configuration.CognitiveServicesConfig
            {
                Name = Environment.GetEnvironmentVariable("CognitiveServicesName"),
                SubscriptionKey = Environment.GetEnvironmentVariable("CognitiveServicesKey"),
                SubscriptionKeyAlternate = Environment.GetEnvironmentVariable("CognitiveServicesKey"),
            });

            using (var sr = new StreamReader(myBlob))
            {
                var fullContent = sr.ReadToEnd();
                var desiredLanguages = new string[] { "de", "es", "fr", "pt",  "it", "nl" };

                var responses = translateClient.Translate(new RequestContent(fullContent), new RequestParameter
                {
                    From = "en",
                    To = desiredLanguages,
                    IncludeAlignment = true
                });

                var storageAccountName = Environment.GetEnvironmentVariable("StorageAccountName");
                var storageAccountKey = Environment.GetEnvironmentVariable("StorageAccountKey");
                var storageAccountEndpoint = Environment.GetEnvironmentVariable("StorageEndpoint");

                var storageCredentials = new StorageCredentials(accountName: storageAccountName, keyValue: storageAccountKey);
                var blobClient = new CloudBlobClient(new Uri(storageAccountEndpoint), storageCredentials);

                var container = blobClient.GetContainerReference("translations");
                container.CreateIfNotExists();

                foreach (var response in responses)
                {
                    foreach(var translation in response.Translations)
                    {
                        var blob = container.GetBlockBlobReference($"{translation.To}.txt");
                        blob.UploadText(translation.Text);
                    }
                }
            }
        }
    }
}


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In summary, Azure Functions will get the content of the original text that will upload into the Storage Account defined through the connection string StorageConnectionString. The content can be accessed through &lt;code&gt;myBlob&lt;/code&gt; variable.&lt;br&gt;
We're reading the content using the StreamReader class, then creating a string array with the languages we want to translate from the original English content.&lt;/p&gt;

&lt;p&gt;Then, we getting some environment variables (we'll define on Azure Portal when we create the Azure Functions), and lastly we're accessing the storage account once again, but this time to store the translated text.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hosting the created code
&lt;/h2&gt;

&lt;p&gt;First, let's create the storage account:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bs1b1Bgk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/o398yk9oeaygtejljyrl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bs1b1Bgk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/o398yk9oeaygtejljyrl.png" alt="Creating a storage account"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9DLRwIpV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2q2r82cblxz9sbzvkz66.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9DLRwIpV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2q2r82cblxz9sbzvkz66.png" alt="Creating a storage account part 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then's let's create the azure functions and get the publish profile to simplify our deploy process:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xiZYHSP7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5lafm4rrip49ebomgw5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xiZYHSP7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5lafm4rrip49ebomgw5b.png" alt="Creating an Azure Function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vmiA_ZwQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wna2uqyzs46f6eu8n4vu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vmiA_ZwQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wna2uqyzs46f6eu8n4vu.png" alt="Creating and Azure Function 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After it's ready, we can get the publish profile through the overview tab:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pmu6wEM4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/btrz16hmix03xv51kdiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pmu6wEM4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/btrz16hmix03xv51kdiw.png" alt="Getting the publish profile"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's use our Visual Studio to publish our code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--71mbIQxG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/h0wetsoamoxpro07d2uh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--71mbIQxG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/h0wetsoamoxpro07d2uh.png" alt="Publishing the Azure Function Project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly let's create the environment variables clicking on the configuration link also from the Overview Tab:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lcoTPuI---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/p6pkrawwsjtwpw5iwjjv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lcoTPuI---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/p6pkrawwsjtwpw5iwjjv.gif" alt="Creating the environment Settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's see everything in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zew4XQQL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/c2i2r3po51tepcoetju9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zew4XQQL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/c2i2r3po51tepcoetju9.gif" alt="Testing our application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The full language support can be found in here: &lt;a href="https://docs.microsoft.com/en-us/azure/cognitive-services/translator/language-support"&gt;https://docs.microsoft.com/en-us/azure/cognitive-services/translator/language-support&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>cognitiveservices</category>
      <category>azurefunctions</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Implementing a Serverless Saga Orchestrator</title>
      <dc:creator>Thiago Custódio</dc:creator>
      <pubDate>Fri, 13 Sep 2019 00:34:51 +0000</pubDate>
      <link>https://forem.com/thdotnet/implementing-a-serverless-saga-orchestrator-50d6</link>
      <guid>https://forem.com/thdotnet/implementing-a-serverless-saga-orchestrator-50d6</guid>
      <description>&lt;blockquote&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"&gt;https://docs.microsoft.com/azure/azure-functions&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;No matter which tech event you attend, there will be someone talking about Microservices. It may not be for you at this moment but it's a fact that Microservices architecture advances loosely coupled services which can be developed, deployed and scaled independently. This architecture style also bring some challenges to the table and I'll address one of them in this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Saga Pattern
&lt;/h2&gt;

&lt;p&gt;In order to ensure data consistency across multiple services, we often implement the Saga pattern: a sequence of local transactions. If a local transaction fails for some reason the Saga executes a series of compensating transactions that undo the changes that were made by the preceding local transactions.&lt;/p&gt;

&lt;p&gt;This idea is not new, I've learned about it many years ago from my friend and professor Felipe Oliveira (@scaphe), but on that time it was applied to Services Oriented Architectures (SOA). There are two ways to implement the Saga Pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Choreography: each local transaction publishes domain events that trigger the execution of transactions in other services;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Orchestration:the logic and order of execution lives on an orchestrator that commits / rollback all the phases related to that business logic;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using Azure Functions in addition with Durable Functions, you can easily implement a serverless Saga Orchestrator (using FanOut and/or Function Chains):&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample
&lt;/h2&gt;

&lt;p&gt;In order to keep this example simple, I'll leave just the orchestrator logic in this article:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public static class OrderSaga
    {
        [FunctionName("OrderSaga")]
        public static async Task&amp;lt;bool&amp;gt; RunOrchestrator(
            [OrchestrationTrigger] DurableOrchestrationContext context)
        {
            var orderId = context.GetInput&amp;lt;Guid&amp;gt;();

            Task&amp;lt;bool&amp;gt; orderResponse = context.CallActivityAsync&amp;lt;bool&amp;gt;("OrderActivity", orderId);
            Task&amp;lt;bool&amp;gt; paymentResponse = context.CallActivityAsync&amp;lt;bool&amp;gt;("PaymentActivity", orderId);

            await Task.WhenAll(orderResponse, paymentResponse);

            if (orderResponse.Result == false || paymentResponse.Result == false)
            {
                await context.CallActivityAsync("RollbackOrderActivity", orderId);
                await context.CallActivityAsync("RollbackPaymentActivity", orderId);

                return false;
            }

            return true;
        }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  What is happening under the hood?
&lt;/h2&gt;

&lt;p&gt;Durable functions expose an endpoint where we can monitor the progress and the output of each activity. It also persists the output from each activity and it has retry logic implemented by nature. All you have to do is implement the success / failure logics into your activities, then use the orchestrator to commit or rollback each phase, just what we've did previously.&lt;/p&gt;

&lt;h2&gt;
  
  
  More information
&lt;/h2&gt;

&lt;p&gt;You can find more information in the following links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Microservices: &lt;a href="https://microservices.io"&gt;Microservices.io&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Saga Pattern: &lt;a href="https://microservices.io/patterns/data/saga.html"&gt;Saga Pattern&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Durable Functions on: &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview"&gt;Docs Azure&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This Sample available on my Github: &lt;a href="https://github.com/thdotnet/ServerlessSaga"&gt;Thdotnet&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>azure</category>
      <category>serverless</category>
      <category>serverlessseptember</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
