<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bervianto Leo Pratama</title>
    <description>The latest articles on DEV Community by Bervianto Leo Pratama (@berviantoleo).</description>
    <link>https://dev.to/berviantoleo</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%2F90909%2F4c11951a-d3a9-463c-8e6c-2e9448366906.jpg</url>
      <title>DEV Community: Bervianto Leo Pratama</title>
      <link>https://dev.to/berviantoleo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/berviantoleo"/>
    <language>en</language>
    <item>
      <title>Migration and Modernisation with Kiro CLI</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Sat, 04 Apr 2026 05:45:49 +0000</pubDate>
      <link>https://dev.to/berviantoleo/migration-and-modernisation-with-kiro-cli-24ga</link>
      <guid>https://dev.to/berviantoleo/migration-and-modernisation-with-kiro-cli-24ga</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Once upon a time, there was a developer who needed to keep updating the dependencies of each tool/product/software. There is a dependabot which still helpful for updating minor versions. However, it will need a manual update/migration whenever a major version comes. Migrating to a major version is frustrating for me if I need to update it in bulk. Updating only one app is pretty fine, but how about multiple apps? I believe we will stop doing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Era
&lt;/h2&gt;

&lt;p&gt;The AI (Artificial Intelligence) era has come. Much automation can be achieved by AI. I have a good belief that I can migrate much more easily whenever I use AI. Not like the old age, which needs many manual changes, especially the breaking changes!&lt;/p&gt;

&lt;h2&gt;
  
  
  Migration as Vibes
&lt;/h2&gt;

&lt;p&gt;I'm starting the migration as vibes. So, I only put a simple prompt to know how the AI will work. In this case, I tested Kiro CLI as an example.&lt;/p&gt;

&lt;p&gt;I have many legacy codes which still being used with &lt;a href="https://cli.vuejs.org/guide/cli-service.html" rel="noopener noreferrer"&gt;Vue CLI&lt;/a&gt;. Vue CLI is in Maintenance Mode, so many tools are deprecated and cannot adapt to the newer version of Typescript, Node, etc. It was frustrating while trying to migrate it to Vite. Many dependencies need to be changed.&lt;/p&gt;

&lt;p&gt;Surprisingly, I am amazed by the result of the simple prompt. It was a success to migrate a bunch of my repos, and at least it produced a basic migration.&lt;/p&gt;

&lt;p&gt;Example simple prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Migrate to Vite from Vue CLI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, that simple prompt is not recommended. :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson Learned
&lt;/h2&gt;

&lt;p&gt;I learned how to create a good prompt. I tried a basic/simple prompt in multiple repositories. The result? I need to change some code manually multiple times. I'm using a library that will raise an error by Vite, I "can" suppress the error as a warning, but I forgot to apply it in multiple projects. So I need to apply it multiple times. I should add more specific extra instructions for migration so I don't need to update it manually frequently.&lt;/p&gt;

&lt;h2&gt;
  
  
  The list of repo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Migrating to Vite
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/bervProject/Pulau-Sebuku-GIS" rel="noopener noreferrer"&gt;https://github.com/bervProject/Pulau-Sebuku-GIS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bervProject/liff-exploration" rel="noopener noreferrer"&gt;https://github.com/bervProject/liff-exploration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bervProject/siwb-ui" rel="noopener noreferrer"&gt;https://github.com/bervProject/siwb-ui&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Related to Upgrading version
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/bervProject/belitung-information-center" rel="noopener noreferrer"&gt;https://github.com/bervProject/belitung-information-center&lt;/a&gt; (Upgrading Angular, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/bervProject/my-personal-web-angular" rel="noopener noreferrer"&gt;https://github.com/bervProject/my-personal-web-angular&lt;/a&gt; (Upgrading Angular)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Future
&lt;/h2&gt;

&lt;p&gt;In the future, I will try to automate this and use a correct prompt. So, it should be automated; I only need to review and approve. :) Let's see.&lt;/p&gt;

&lt;p&gt;Thank you for reading. I hope you get an insight.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxiejes2iz5zvcn73g7w5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxiejes2iz5zvcn73g7w5.gif" alt="Thanks GIF" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>kiro</category>
      <category>kirocli</category>
      <category>migration</category>
    </item>
    <item>
      <title>re:Cap 2025 by AWS User Group Jakarta</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Sat, 31 Jan 2026 12:12:26 +0000</pubDate>
      <link>https://dev.to/aws-builders/recap-2025-by-aws-user-group-jakarta-f8c</link>
      <guid>https://dev.to/aws-builders/recap-2025-by-aws-user-group-jakarta-f8c</guid>
      <description>&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;AWS User Group Jakarta hosted re:Cap 2025. It was a great opportunity to speak at re:Cap 2025. For more information, you can visit,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/aws-ug-jakarta/events/312636882/?eventOrigin=notifications&amp;amp;notificationId=%3Cinbox%3E%21306480235-1769723328220" rel="noopener noreferrer"&gt;Meetup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jakarta.awscommunity.id/events/reinvent-recap-2025/" rel="noopener noreferrer"&gt;AWS UG Jakarta - Event&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Session
&lt;/h2&gt;

&lt;p&gt;I was talking about some announcements that might be interested for developers. You may get &lt;a href="https://docs.google.com/presentation/d/106EWTPkdjf3fovBD5T0Sm-LPHPTvP2ZxdK3-brA5Wuc/edit?usp=sharing" rel="noopener noreferrer"&gt;my slide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The focus is more on Lambda and AWS Transform. It's quite inline with migration and modernization.&lt;/p&gt;

&lt;p&gt;Migration and modernization are not simple tasks. That's why AWS Transform may help some organizations to migrate and modernise. However, AWS Transform may need to consider the security concern.&lt;/p&gt;

&lt;p&gt;I'm quite excited about Lambda Durable Function. It's quite helpful to extend the decision moving app to Lambda. Whenever configuring "complex" infrastructure, it may be hard to troubleshoot and migrate. Using a Lambda Durable Function may be a better solution for some cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Photos from the Organizer
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89z02ugq30szmdshrup1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89z02ugq30szmdshrup1.jpg" alt="Presenting 2" width="800" height="794"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kqdd94ui7rmee969kl2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kqdd94ui7rmee969kl2.jpg" alt="Presenting" width="800" height="796"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;If you are interested in another topic, feel free to reach out to the speakers. It's really great to attend re:cap 2025 by AWS UG Jakarta.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flkg9s3utxcwjrgy0pvca.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flkg9s3utxcwjrgy0pvca.gif" alt="Happy GIF" width="480" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>modernise</category>
      <category>news</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Importing my AWS IAM Role to Terraform using Terraform Search</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Fri, 17 Oct 2025 08:24:20 +0000</pubDate>
      <link>https://dev.to/berviantoleo/importing-my-aws-iam-role-to-terraform-2n4m</link>
      <guid>https://dev.to/berviantoleo/importing-my-aws-iam-role-to-terraform-2n4m</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover image is generated by AI&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;A long time ago... I want to manage my IAM Role with Terraform. But, I'm quite lazy for writing it manually... Especially for my existing IAM Role. I heard about &lt;strong&gt;Terraform Search&lt;/strong&gt;, which helps me import existing resources to write the resource configuration! Wow!&lt;/p&gt;

&lt;p&gt;Imagine you write the query something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt; &lt;span class="nx"&gt;dev&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Run this command.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform query &lt;span class="nt"&gt;-generate-config-out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;generated.tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Boom! You got a generated resource file with the import blocks.&lt;/p&gt;

&lt;p&gt;Easy, right?&lt;/p&gt;
&lt;h2&gt;
  
  
  How did I do?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Prerequisite
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Terraform 1.14.x (still beta right now...)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to read more, please visit &lt;a href="https://developer.hashicorp.com/terraform/language/v1.14.x/import/bulk" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind. Terraform Search supports are based on the Terraform provider.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpetw83heja7cbiwclfqv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpetw83heja7cbiwclfqv.png" alt="Documentation"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Run it locally
&lt;/h3&gt;

&lt;p&gt;Okay, you need to do it locally because HCP won't have the beta right now, except that Terraform 1.14 has been released. So, basically, these are my steps. In this case, I want to manage the state in HCP Terraform.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Terraform 1.14.x in Local&lt;/li&gt;
&lt;li&gt;Ensure you have the AWS Credentials in your local.&lt;/li&gt;
&lt;li&gt;Configure a workspace in HCP Terraform. Ensure you have the AWS Credentials. But temporarily set it as local execution.&lt;/li&gt;
&lt;li&gt;Write the &lt;code&gt;main.tf&lt;/code&gt; to configure the provider, in this case AWS provider.&lt;/li&gt;
&lt;li&gt;Write the &lt;code&gt;.tfquery.hcl&lt;/code&gt; file (look above section).&lt;/li&gt;
&lt;li&gt;Let's init first. &lt;code&gt;terraform init&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run the query command &lt;code&gt;terraform query -generate-config-out=generated.tf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Copy only resources that I want to manage.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;terraform plan&lt;/code&gt; just to ensure it will import!&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;terraform apply&lt;/code&gt; if I'm sure of the configuration.&lt;/li&gt;
&lt;li&gt;Now my IAM Roles are managed by HCP Terraform!&lt;/li&gt;
&lt;li&gt;You may now change the execution to HCP Terraform (if you want to run it there).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It may expose your AWS Account ID and some information. Before you commit those codes, you may need to extract some information to create some variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwhiy9tgkzgu0b3csg1d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwhiy9tgkzgu0b3csg1d.png" alt="HCP Result"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;You can visit my repo here.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/bervProject" rel="noopener noreferrer"&gt;
        bervProject
      &lt;/a&gt; / &lt;a href="https://github.com/bervProject/AWSSecurityAsACode" rel="noopener noreferrer"&gt;
        AWSSecurityAsACode
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      AWS Security as a Code for BervProjects
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;My First AWS Security as Code&lt;/h1&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Generate the resources import&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;terraform query -generate-config-out=generated.tf&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;./generate.sh&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;LICENSE&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;MIT&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/bervProject/AWSSecurityAsACode" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  Thank you
&lt;/h2&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

&lt;p&gt;If you have any feedback, feel free to comment here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fencrypted-tbn0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcTZiYsNkgJKFu0dZiJuwNVdK5Pk9PqUtYMhQw%26s" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fencrypted-tbn0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcTZiYsNkgJKFu0dZiJuwNVdK5Pk9PqUtYMhQw%26s" alt="Gracias GIF"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>aws</category>
      <category>terraform</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Enhancing developer experience with Vagrant</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Fri, 26 Sep 2025 05:21:15 +0000</pubDate>
      <link>https://dev.to/berviantoleo/enhancing-developer-experience-with-vagrant-ai0</link>
      <guid>https://dev.to/berviantoleo/enhancing-developer-experience-with-vagrant-ai0</guid>
      <description>&lt;p&gt;This is a part of my &lt;a href="https://www.hashicorp.com/en/conferences/hashiconf/agenda/9-25/enhancing-developer-experience-with-vagrant" rel="noopener noreferrer"&gt;HashiConf 2025&lt;/a&gt; talks.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://1drv.ms/p/c/e84502f01965f7c5/EY_e1LTdLVpBvL8826LOQEUBbavF6BJGlHi_mlo7JOejpQ?e=HKXaJQ" rel="noopener noreferrer"&gt;Original Slides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;As a developer, it's quite common to get an issue which not replicable. It's either an undetailed or an assumption replication of steps, a configuration issue, an environment issue, etc. I believe some developers face issues when in production it doesn't work, but in their local was working. There is a common slogan, "it's work in my machine." So, why don't we bring our machine then?&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;We need to kill the configuration/environment issue. There is a great tool called Vagrant. I want to emphasize why Vagrant? Because it promises consistency. When in my machine works, of course, in yours, and should be productions!&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When I developed some functionality, there was an issue that only happened in production. Either because different operating system, a different configuration, etc. Of course, when we use Vagrant, we are able to use the same operating system.&lt;/li&gt;
&lt;li&gt;How about the configuration? Yes, we can ensure the same config as production. It doesn't mean you will have the same architecture, but at least you have the prototype.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Trade Off
&lt;/h2&gt;

&lt;p&gt;Every choice will have a trade-off. For example, we will face the power of the host machine. Not all organizations will choose a very fancy specification. This will become a bottleneck. When they don't want to switch into the same operating system, but don't want to spend more money on providing more powerful development devices.&lt;/p&gt;

&lt;p&gt;Well, let's talk about why we use Docker directly. Of course, I will say yes, if...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The operating system is the same as our target server.&lt;/li&gt;
&lt;li&gt;Having a mechanism to have the same configuration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I faced some organizations having their developers which different tools, different operating systems, which is not appropriate. Okay, for example, I have a Windows operating system, but I want to run Docker. Oh well, we may say, oh, that's better. It's more reasonable now, lighter.&lt;/p&gt;

&lt;p&gt;Well, I was part of modernization and or refactoring from .NET Framework to .NET Core, which supports more operating systems. Back then, I faced a lot of problems when we started containerizing it to become a Linux container. Either it's only running in my machine, or just environment issues.&lt;/p&gt;

&lt;p&gt;For example, oh, I can run it in my local environment because I have some proper configurations. But the production doesn't know it, which is not a good one. Then, how about talking about the changes to the operation team regarding changes. Well, how long will it take? They have some BAU (Business As Usual). Some requests may not be taken into account.&lt;/p&gt;

&lt;p&gt;Oh no, so what will we do? Imagine...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The developer can make some changes in their Vagrantfile.&lt;/li&gt;
&lt;li&gt;We have set the automatic system to detect the changes.&lt;/li&gt;
&lt;li&gt;If we get the changes, we start to sync them with production.&lt;/li&gt;
&lt;li&gt;Yeay! We win it!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But, but, ... I can't say the current state of Vagrant is developer-friendly. It's a little bit operations team part. I would say it's a shared responsibility between the developer and operations. Well, at least it's a code, developers should learn it (sorry).&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The providers may not matter. I select VirtualBox, because most of us are more familiar with it, but please select any providers that fit with your compliance. Maybe the other VM Virtualization will work. Please take note, why we don't choose Docker as a provider, it's a bit complex (oh, I mean more confusing) than the other. Because it will run a VM whenever it's not supporting Linux containerization.&lt;/li&gt;
&lt;li&gt;Choose any provisioner that meets your requirements. I love how Docker provisioner works. Even sometimes I still need &lt;strong&gt;shell&lt;/strong&gt;. I really hope the provisioner will grow up. Why? So we can easily get the high-level of Vagrantfile (without AI, of course, sorry AI).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I understand we can improve our work with AI, but please understand the fundamentals. It will really help instead of blindly using AI, and (boom), you don't know what AI said.&lt;/p&gt;

&lt;p&gt;Finally, feel free to give any feedback. Any feedback is welcome, even if you do not agree with this article/supplement. I just want to share my perspective. Every team/organization may have its own challenges, which is why sharing is caring. I really love to learn how they tackle their challenges. It's really inspiring!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjlugcax0yk31kp13ooo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjlugcax0yk31kp13ooo.gif" alt="Thanks GIF" width="220" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vagrant</category>
      <category>devops</category>
      <category>devex</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Pengalaman Pertama menghadiri AWS Summit Jakarta 2025 sebagai Speaker</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Sat, 30 Aug 2025 04:20:31 +0000</pubDate>
      <link>https://dev.to/aws-builders/pengalaman-pertama-menghadiri-aws-summit-jakarta-2025-sebagai-speaker-4i8a</link>
      <guid>https://dev.to/aws-builders/pengalaman-pertama-menghadiri-aws-summit-jakarta-2025-sebagai-speaker-4i8a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover blog di-generate oleh AI&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Pembukaan
&lt;/h2&gt;

&lt;p&gt;Halo, semuanya!&lt;/p&gt;

&lt;p&gt;Ini merupakan tulisan pertama saya dalam bahasa Indonesia di sini. Saya sengaja menuliskannya dalam Bahasa Indonesia karena acara AWS Summit Jakarta 2025 ini diadakan di Indonesia. Acaranya diadakan tanggal 7 Agustus 2025.&lt;/p&gt;

&lt;p&gt;Saya sangat senang bertemu dengan rekan-rekan AWS Community Builder. Bertemu juga dengan rekan-rekan AWS User Group Jakarta. Apalagi waktu itu akhirnya bertemu muka dengan Shafraz Rahim (AWS - Senior Program Manager - Community, APJC) dan Jason Dunn (AWS CB Program Manager), yang biasanya bertemu di media sosial saja. :D&lt;/p&gt;

&lt;p&gt;Saya waktu itu berkesempatan untuk membicarakan topik Amazon Q Developer dengan kasus modernisasi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Foto-Foto
&lt;/h2&gt;

&lt;p&gt;Berikut foto-fotonya. Hehehe...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ini waktu saya berbicara&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiu2cxjtbbtt8j67htqib.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiu2cxjtbbtt8j67htqib.jpg" alt="Saat Berbicara"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Foto Grup Developer Lounge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotcwpu6n4ehvevswk4py.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotcwpu6n4ehvevswk4py.jpg" alt="Foto Grup Developer Lounge"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ini makan malam setelah semuanya selesai.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5x95il94n2ydes9d80v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5x95il94n2ydes9d80v.jpg" alt="Makan-Makan"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tambahan
&lt;/h2&gt;

&lt;p&gt;Berikut ini &lt;a href="https://1drv.ms/p/c/e84502f01965f7c5/IQSmucH97iPMRawP4f1vRj-jAYOWKcqDw8fAXn74cwAMSXM" rel="noopener noreferrer"&gt;slide-deck&lt;/a&gt; yang saya gunakan.&lt;/p&gt;

&lt;p&gt;Berikut ini juga video-nya.&lt;/p&gt;

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

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/jLlOUdigydk"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

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

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/tfuk94eXIvY"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Terima kasih
&lt;/h2&gt;

&lt;p&gt;Terima kasih untuk teman-teman yang sudah hadir juga!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzwkh42zcsm9ri5ffikul.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzwkh42zcsm9ri5ffikul.png" alt="Terima kasih"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Gambar "Thank you" di-generate oleh AI&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>aws</category>
      <category>awssummit</category>
      <category>devjournal</category>
      <category>experience</category>
    </item>
    <item>
      <title>Continuing ShortenUrl with Redis 8</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Sat, 09 Aug 2025 06:17:20 +0000</pubDate>
      <link>https://dev.to/berviantoleo/continuing-shortenurl-with-redis-8-4o9o</link>
      <guid>https://dev.to/berviantoleo/continuing-shortenurl-with-redis-8-4o9o</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/redis-2025-07-23"&gt;Redis AI Challenge&lt;/a&gt;: Beyond the Cache&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I was building ShortenUrl, which utilizes Redis Stack. Now, I'll try to utilize Redis 8 and add some features, for example, statistics.&lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/berviantoleo/simple-shorten-url-using-redis-and-auth0-lk7" class="crayons-story__hidden-navigation-link"&gt;Simple Shorten URL using Redis and Auth0&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/berviantoleo" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F90909%2F4c11951a-d3a9-463c-8e6c-2e9448366906.jpg" alt="berviantoleo profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/berviantoleo" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Bervianto Leo Pratama
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Bervianto Leo Pratama
                
              
              &lt;div id="story-author-preview-content-1169651" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/berviantoleo" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F90909%2F4c11951a-d3a9-463c-8e6c-2e9448366906.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Bervianto Leo Pratama&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/berviantoleo/simple-shorten-url-using-redis-and-auth0-lk7" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 28 '22&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/berviantoleo/simple-shorten-url-using-redis-and-auth0-lk7" id="article-link-1169651"&gt;
          Simple Shorten URL using Redis and Auth0
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/redishackathon"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;redishackathon&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/redis"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;redis&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/dotnet"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;dotnet&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/berviantoleo/simple-shorten-url-using-redis-and-auth0-lk7" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;3&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/berviantoleo/simple-shorten-url-using-redis-and-auth0-lk7#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            1 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  New Feature - Stats
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fec2rlv4o2otw4d5p0yid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fec2rlv4o2otw4d5p0yid.png" alt="Stats"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Redis 8
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Details of usage, mostly in README.ME. I'll explain what the highlight features.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;As a primary database, I'm using JSON for storing in Redis. It's speedy!&lt;/li&gt;
&lt;li&gt;Using aggregate/order in Redis.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>redischallenge</category>
      <category>devchallenge</category>
      <category>database</category>
      <category>ai</category>
    </item>
    <item>
      <title>Asking Amazon Q for fixing the Bug Regarding Uploading an Attachment using Amazon SES</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Tue, 06 May 2025 14:43:45 +0000</pubDate>
      <link>https://dev.to/aws-builders/asking-amazon-q-for-fixing-the-bug-regarding-uploading-an-attachment-using-amazon-ses-1me1</link>
      <guid>https://dev.to/aws-builders/asking-amazon-q-for-fixing-the-bug-regarding-uploading-an-attachment-using-amazon-ses-1me1</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/aws-amazon-q-v2025-04-30"&gt;Amazon Q Developer "Quack The Code" Challenge&lt;/a&gt;: Crushing the Command Line&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;If you have read my previous post, I got the bug when uploading the attachment. Since I would like to crack the bug. Let's ask Amazon Q!&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Just a simple prompt for fixing the code.&lt;/p&gt;

&lt;p&gt;Prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;My AWS Lambda function has a bug when uploading the attachment using ses service, Please examine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Summary of the changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzn66duoz0s14zl09o1kh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzn66duoz0s14zl09o1kh.png" alt="Summary"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/bervProject/MergePDFOnline/commit/6769f43262369be4ee1ad4c04b384be0c3665691" rel="noopener noreferrer"&gt;The commit&lt;/a&gt; made by Amazon Q&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Fixed" Email&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fbg78k0gyt9uzcj1347.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6fbg78k0gyt9uzcj1347.png" alt="Fixed Email"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, but it's not really fixed my code. However, it makes me think there is some documentation or news regarding the limit. I found it &lt;a href="https://aws.amazon.com/about-aws/whats-new/2021/09/amazon-ses-emails-message-40mb/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. So, I decided to ask Amazon Q to increase the attachment limit.&lt;/p&gt;

&lt;p&gt;Of course, the issue still exists; it seems the PDF has been corrupted when sending the email. I've checked the size when downloading, it has the correct size. But the attached file size was doubled. So, I decided to ask Amazon Q to compress it.&lt;/p&gt;

&lt;p&gt;Very unfortunate, I can't open the zip file! So, I think the bug occurs when sending the base64 data, which introduces a corrupted file.&lt;/p&gt;

&lt;p&gt;I hope it will be fixed when I identify the SDK with Amazon Q later. But not now, sorry.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code Repository
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/bervProject" rel="noopener noreferrer"&gt;
        bervProject
      &lt;/a&gt; / &lt;a href="https://github.com/bervProject/MergePDFOnline" rel="noopener noreferrer"&gt;
        MergePDFOnline
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Merge PDF Online
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;MergePDFOnline&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;Merge PDF Online&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;LICENSE&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;    Copyright (C) 2022 Bervianto Leo Pratama

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see &amp;lt;https://www.gnu.org/licenses/&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/bervProject/MergePDFOnline" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  How I Used Amazon Q Developer
&lt;/h2&gt;

&lt;p&gt;Writing a prompt with specific context.&lt;/p&gt;

&lt;p&gt;Sadly, it's not fixed now. I hope it will, later.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Updates:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Voila! I fixed it just by providing &lt;code&gt;ContentTransferEncoding = "BASE64"&lt;/code&gt;. The SDK always converts my file to base64, but the encoding was being set to &lt;code&gt;SEVEN_BIT&lt;/code&gt;. Of course, it's not matched encoding!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tuz583gj1f8pcexoi76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tuz583gj1f8pcexoi76.png" alt="Fixed Attachment"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>awschallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Amazon Q: Assisting with My Monthly Maintenance</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Tue, 06 May 2025 12:41:47 +0000</pubDate>
      <link>https://dev.to/berviantoleo/amazon-q-assisting-with-my-monthly-maintenance-3mpd</link>
      <guid>https://dev.to/berviantoleo/amazon-q-assisting-with-my-monthly-maintenance-3mpd</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/aws-amazon-q-v2025-04-30"&gt;Amazon Q Developer "Quack The Code" Challenge&lt;/a&gt;: Crushing the Command Line&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Each month, I had various devices that were not prepared to update the scripts for updating the applications and systems. Searching for the appropriate commands may take time. I remembered the tasks that I should do, but unfortunately forgot the scripts or commands. Let's ask Amazon Q for help to prepare the scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using Amazon Q Chat
&lt;/h3&gt;

&lt;h4&gt;
  
  
  First Task
&lt;/h4&gt;

&lt;p&gt;Updating essential apps, for example, AWS CLI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First Simple Prompt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy13eixycloxxluwlviji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy13eixycloxxluwlviji.png" alt="Ask a simple script"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First Simple Prompt Verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwc5qve60vmis2lw5eji1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwc5qve60vmis2lw5eji1.png" alt="Run the script"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Second Task
&lt;/h4&gt;

&lt;p&gt;Cleaning caches&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Second Simple Prompt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3zblid6klknl8rpd0nm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3zblid6klknl8rpd0nm.png" alt="Prompt Cache Cleaning"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Second Simple Prompt Verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F09gz96v1okur30pu5gkm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F09gz96v1okur30pu5gkm.png" alt="Second Verification"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Third Task
&lt;/h4&gt;

&lt;p&gt;Back up the scripts into a directory and/or a repository.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Moving the scripts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5036ds8iiqxl29pdoafu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5036ds8iiqxl29pdoafu.png" alt="Moving scripts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding the context and creating a README&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9o8rx552vm1azvsrbvya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9o8rx552vm1azvsrbvya.png" alt="Add context and create a readme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, I can also create the repository on GitHub without leaving the chat! Awesome!&lt;/p&gt;

&lt;p&gt;Example prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create the repository in GitHub using the GitHub CLI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I've set up the CLI before. So it will be done seamlessly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Code Repository
&lt;/h2&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/berviantoleo" rel="noopener noreferrer"&gt;
        berviantoleo
      &lt;/a&gt; / &lt;a href="https://github.com/berviantoleo/maintenance-scripts" rel="noopener noreferrer"&gt;
        maintenance-scripts
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Maintenance Scripts&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;This directory contains scripts for various system maintenance tasks, primarily focused on package manager cache cleanup and AWS CLI updates.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Available Scripts&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Package Manager Cache Cleanup&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Script:&lt;/strong&gt; &lt;code&gt;clear-package-caches.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This script cleans the caches for multiple package managers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;npm: Clears the npm cache using &lt;code&gt;npm cache clean --force&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;apt: Cleans the apt cache using &lt;code&gt;sudo apt-get clean&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;NuGet: Clears NuGet caches using either &lt;code&gt;nuget locals all -clear&lt;/code&gt; or &lt;code&gt;dotnet nuget locals all --clear&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;pip: Purges the pip cache using &lt;code&gt;pip cache purge&lt;/code&gt; or &lt;code&gt;pip3 cache purge&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The script checks for the presence of each package manager before attempting to clear its cache, so it's safe to run even if some package managers aren't installed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;./clear-package-caches.sh&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;AWS CLI Update Scripts&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;AWS CLI Version 2 Update&lt;/h4&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Script:&lt;/strong&gt; &lt;code&gt;update-aws-cli-v2.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Updates AWS CLI version 2 (recommended version) by:&lt;/p&gt;


&lt;ol&gt;

&lt;li&gt;Downloading the latest installer from AWS&lt;/li&gt;

&lt;li&gt;Extracting and running the update process&lt;/li&gt;

&lt;li&gt;Cleaning…&lt;/li&gt;

&lt;/ol&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/berviantoleo/maintenance-scripts" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  How I Used Amazon Q Developer
&lt;/h2&gt;

&lt;p&gt;I write a concise prompt for my recurring tasks. Detailed usage, explained in each section of the Demo.&lt;/p&gt;

&lt;p&gt;Tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write the prompt as concisely as you can.&lt;/li&gt;
&lt;li&gt;Adding context will be helpful.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>awschallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Migrating from Amazon Simple Email Service API V1 to V2</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Sun, 27 Apr 2025 14:26:18 +0000</pubDate>
      <link>https://dev.to/aws-builders/migrating-from-amazon-simple-email-v1-to-v2-46n4</link>
      <guid>https://dev.to/aws-builders/migrating-from-amazon-simple-email-v1-to-v2-46n4</guid>
      <description>&lt;p&gt;I'm interested in the new feature that allows me to send attachments in my email. Previously, my flow sent the temporary public link to see the result of my merged PDF. However, it may not be the case!&lt;/p&gt;

&lt;p&gt;So, I'll try to move to the V2 API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr57h95sf7em19zmlmnj8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr57h95sf7em19zmlmnj8.gif" alt="Hooray GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/ses/latest/dg/attachments.html" rel="noopener noreferrer"&gt;AWS Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installing the new SDK and removing the previous SDK
&lt;/h2&gt;

&lt;p&gt;I changed the SDK dependency from V1 to V2.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reference:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-    &amp;lt;PackageReference Include="AWSSDK.SimpleEmail" Version="3.7.402.82" /&amp;gt;
&lt;/span&gt;&lt;span class="gi"&gt;+    &amp;lt;PackageReference Include="AWSSDK.SimpleEmailV2" Version="3.7.410.12" /&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Changing the code
&lt;/h2&gt;

&lt;p&gt;Previously, I had a feature flag for using HTML format. However, I will remove it and use the HTML format as the default. You may refer to my previous session regarding the feature flag presentation. I haven't written it yet. Please let me know if you want me to share it. Previously limited to AWS Commnity Indonesia event.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://sessionize.com/s/berviantoleo/rilis-aws-lambda-dengan-aman-melalui-memanfaatkan-/109551" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsessionize.com%2Fimage%2Fcada-400o400o2-TuqWM5riiRkaNpFYsAK8ne.jpg" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://sessionize.com/s/berviantoleo/rilis-aws-lambda-dengan-aman-melalui-memanfaatkan-/109551" rel="noopener noreferrer" class="c-link"&gt;
            Bervianto Leo Pratama's Speaker Profile @ Sessionize
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Passionate Software Engineer who loves to learn DevOps, Microservices, and Cloud Computing...
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsessionize.com%2Ffavicon"&gt;
          sessionize.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Let's focus on the required changes. I've added some improvements to my repository for readability.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Updating the reference from V1 to V2.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- using Amazon.SimpleEmail;
&lt;/span&gt;&lt;span class="gi"&gt;+ using Amazon.SimpleEmailV2;
&lt;/span&gt;&lt;span class="gd"&gt;- using Amazon.SimpleEmail.Model;
&lt;/span&gt;&lt;span class="gi"&gt;+ using Amazon.SimpleEmailV2.Model;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-            services.AddAWSService&amp;lt;IAmazonSimpleEmailService&amp;gt;();
&lt;/span&gt;&lt;span class="gi"&gt;+            services.AddAWSService&amp;lt;IAmazonSimpleEmailServiceV2&amp;gt;();
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-        private readonly IAmazonSimpleEmailService _amazonSimpleEmailService;
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+        private readonly IAmazonSimpleEmailServiceV2 _amazonSimpleEmailService;
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-            _amazonSimpleEmailService = new AmazonSimpleEmailServiceClient(region);
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+            _amazonSimpleEmailService = new AmazonSimpleEmailServiceV2Client(region);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Complete changes, you may refer to these commits &lt;a href="https://github.com/bervProject/MergePDFOnline/compare/57d9ec9...eeb71c9" rel="noopener noreferrer"&gt;changes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examine the result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9fd485lix6aqyjhsvdw5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9fd485lix6aqyjhsvdw5.png" alt="Run Duration and Memory"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Duration: 12664.70 ms   Billed Duration: 12665 ms   Memory Size: 512 MB Max Memory Used: 322 MB Init Duration: 567.43 ms    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, of course, there are some side effects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, long running duration. So, it means increase the billing! I'll evaluate this change; if needed, I will move the operation (sending the attachment) to another service.&lt;/li&gt;
&lt;li&gt;Second, the memory used is increasing. Well, it's expected, because I will need to download the whole PDF to my Lambda. Of course, I may need to move the workload or reuse the merged file. So, it's not only uploading to the S3, but also using the file for the attachment. Currently, I use a bad approach, which downloads the uploaded file into S3, which increases the network call. The better approach is to reopen the file and upload it again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, I'll still evaluate the current state. When necessary, I'll do more enhancements to my existing environment. So, at least, I will need to reduce the workload time.&lt;/p&gt;

&lt;p&gt;Note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sadly, my attachment (the PDF) gives multiple blank pages. Not sure of the root cause, having some cases. I checked the result in the S3 bucket itself. I can open it as expected. Either the wrong download process or the wrong encoding process. I noticed the file size is quite different from the original file size.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furltahffjxe01yfs737x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furltahffjxe01yfs737x.png" alt="Blank Pages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll try to find out later. :(&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp9qfim3h1e235s3p5zn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp9qfim3h1e235s3p5zn.gif" alt="Sad GIF"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>amazonses</category>
      <category>ses</category>
      <category>migration</category>
    </item>
    <item>
      <title>Mengambil Data Ramalan Cuaca Hari Ini dengan API dari Open Weather</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Tue, 15 Apr 2025 13:40:26 +0000</pubDate>
      <link>https://dev.to/berviantoleo/mengambil-data-ramalan-cuaca-hari-ini-dengan-api-dari-open-weather-5bdg</link>
      <guid>https://dev.to/berviantoleo/mengambil-data-ramalan-cuaca-hari-ini-dengan-api-dari-open-weather-5bdg</guid>
      <description>&lt;h4&gt;
  
  
  Serta Mengambil Data Lokasi dari Geolocation API pada Browser
&lt;/h4&gt;

&lt;h3&gt;
  
  
  Persyaratan — Sebelum Memulai
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API Key Open Weather.&lt;/strong&gt; Mohon dibuat dahulu akunnya ya, nanti akan mendapatkan API Key-nya.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser/Peramban&lt;/strong&gt;. Kalau gak punya nanti buka lamannya menggunakan apa dong? :)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IDE.&lt;/strong&gt; Boleh apapun, yang penting bisa tulis kodenya. Notepad juga boleh.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.&lt;/strong&gt; Versi 18/20 aja ya, kita coba pakai Vite + React kali ini.&lt;/li&gt;
&lt;li&gt;Sudah. Hehe…&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mempersiapkan Proyek
&lt;/h3&gt;

&lt;p&gt;Nah, kita perlu siapin dulu nih proyeknya.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create vite@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Jalankan perintah di atas.&lt;/li&gt;
&lt;li&gt;Isi nama proyek.&lt;/li&gt;
&lt;li&gt;Pilih “Vite + React + Typescript” atau sejenisnya, biar sama nih.&lt;/li&gt;
&lt;li&gt;Masuk ke foldernya, lalu jangan lupa “ &lt;strong&gt;npm install&lt;/strong&gt; ” ya.&lt;/li&gt;
&lt;li&gt;Nah, ada tambahan, kita mau pakai axios. Jadi, ada tambahan perintah &lt;strong&gt;“npm install axios”&lt;/strong&gt; , inget tidak pakai tanda petik.&lt;/li&gt;
&lt;li&gt;Kalau mau jalanin aplikasinya, “ &lt;strong&gt;npm run dev&lt;/strong&gt; ”.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Eksplorasi dan Mengubah Kode
&lt;/h3&gt;

&lt;p&gt;Nah, udah siap nih untuk ubah-ubah kodenya. Pelan-pelan aja ya.&lt;/p&gt;

&lt;p&gt;Kita sekarang mempersiapkan kode untuk ambil lokasi kita dulu aja deh ya.&lt;/p&gt;

&lt;h4&gt;
  
  
  Geolocation API
&lt;/h4&gt;

&lt;p&gt;Tambahin kode ini dulu di berkas &lt;strong&gt;App.tsx&lt;/strong&gt; ya. Tulisnya sebelum &lt;strong&gt;function App()&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Location {
  latitude: number;
  longitude: number;
}

function App() {
  /** sengaja dipotong */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nah, setelah itu kita perlu siapin &lt;em&gt;state&lt;/em&gt;-nya dulu, &lt;em&gt;state&lt;/em&gt;-nya akan kita pakai untuk memanggil API Open Weather ya.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
   const [userLocation, setUserLocation] = useState&amp;lt;Location | null&amp;gt;(null);

   /** sengaja dipotong lagi */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Udah siap aja nih. Yuk, kita sekarang buat fungsi yang akan memanggil Geolocation API dari browser ya.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {   
   const [userLocation, setUserLocation] = useState&amp;lt;Location | null&amp;gt;(null);

   const getUserLocation = () =&amp;gt; {
    // if geolocation is supported by the users browser
    if (navigator.geolocation) {
      // get the current users location
      navigator.geolocation.getCurrentPosition(
        (position) =&amp;gt; {
          // save the geolocation coordinates in two variables
          const { latitude, longitude } = position.coords;
          // update the value of userlocation variable
          setUserLocation({ latitude, longitude });
        },
        // if there was an error getting the users location
        (error) =&amp;gt; {
          console.error('Error getting user location:', error);
        }
      );
    }
    // if geolocation is not supported by the users browser
    else {
      console.error('Geolocation is not supported by this browser.');
    }
  };
  /** sengaja dipotong lagi nih */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oke, seperti ada yang kurang kalau gak ada yang menampilkan nilainya. Jadi kita sekarang bermain di bagian rendernya nih.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  /** sengaja dipotong, tapi ini kode tadi ya... */
  return (
    &amp;lt;&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Geolocation App&amp;lt;/h1&amp;gt;
        {/* create a button that is mapped to the function which retrieves the users location */}
        &amp;lt;button onClick={getUserLocation}&amp;gt;Get User Location&amp;lt;/button&amp;gt;
        {/* if the user location variable has a value, print the users location */}
        {userLocation &amp;amp;&amp;amp; (
          &amp;lt;div&amp;gt;
            &amp;lt;h2&amp;gt;User Location&amp;lt;/h2&amp;gt;
            &amp;lt;p&amp;gt;Latitude: {userLocation.latitude}&amp;lt;/p&amp;gt;
            &amp;lt;p&amp;gt;Longitude: {userLocation.longitude}&amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
        )}
      &amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cobain deh di browser. Kamu harusnya udah bisa menampilkan nilainya nih. Ini contoh aja ya.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2p1l8qmnzt7h7we3qzw7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2p1l8qmnzt7h7we3qzw7.png" width="613" height="383"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Contoh Lat &amp;amp; Long&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Wah, maaf ya disensor. Nanti ketahuan lokasinya. Hehe…&lt;/p&gt;
&lt;h4&gt;
  
  
  Memanggil Open Weather API menggunakan Axios
&lt;/h4&gt;

&lt;p&gt;Sekarang bagian memanggil API Open Weather dengan axios nih.&lt;/p&gt;

&lt;p&gt;Siapin dulu aja nilai yang ingin disimpan, kalau saya simpan cuaca sekarang aja deh. Oh iya, ini ada tambahan &lt;em&gt;loading&lt;/em&gt;, ya biar ala-ala ada prosesnya.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  const [userLocation, setUserLocation] = useState&amp;lt;Location | null&amp;gt;(null);
  const [currentWeather, setCurrentWeather] = useState&amp;lt;string | null&amp;gt;(null);
  const [loading, setLoading] = useState&amp;lt;boolean&amp;gt;(false);
  /** sengaja dipotong lagi dan lagi, tapi ini kode tadi ya... */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nah, kita tulis fungsi untuk mengambil datanya.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {

  /** sengaja dipotong lagi dan lagi, tapi ini kode tadi ya... */
  const getWeather = () =&amp;gt; {
    setLoading(true);
    setTimeout(() =&amp;gt; {
      if (!userLocation) {
        setLoading(false);
        return;
      };
      const apiKey = import.meta.env.VITE_API_KEY;

      axios.get(`https://api.openweathermap.org/data/2.5/weather?lat=${userLocation.latitude}&amp;amp;lon=${userLocation.longitude}&amp;amp;appid=${apiKey}`)
        .then((result) =&amp;gt; {
          setCurrentWeather(result.data.weather[0].main);
        }).catch((err: Error) =&amp;gt; {
          console.error(err);
        }).finally(() =&amp;gt; {
          setLoading(false);
        })

    }, 1000);
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sabar, ini masih belum loh. Sekarang kita siapin tombol untuk memuat cuacanya.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Geolocation App&amp;lt;/h1&amp;gt;
        {/* create a button that is mapped to the function which retrieves the users location */}
        &amp;lt;button onClick={getUserLocation}&amp;gt;Get User Location&amp;lt;/button&amp;gt;
        {/* if the user location variable has a value, print the users location */}
        {userLocation &amp;amp;&amp;amp; (
          &amp;lt;div&amp;gt;
            &amp;lt;h2&amp;gt;User Location&amp;lt;/h2&amp;gt;
            &amp;lt;p&amp;gt;Latitude: {userLocation.latitude}&amp;lt;/p&amp;gt;
            &amp;lt;p&amp;gt;Longitude: {userLocation.longitude}&amp;lt;/p&amp;gt;
            &amp;lt;button onClick={getWeather}&amp;gt;Get Current Weather&amp;lt;/button&amp;gt;
            {loading &amp;amp;&amp;amp; (&amp;lt;div className='loader'&amp;gt;&amp;lt;/div&amp;gt;)}
            {currentWeather &amp;amp;&amp;amp; (&amp;lt;p&amp;gt;Current weather: {currentWeather}&amp;lt;/p&amp;gt;)}
          &amp;lt;/div&amp;gt;
        )}
      &amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eh iya, tadi belum memberikan css yang digunakan untuk “loader” ya. Ini contoh aja ya. Bebas aja mau pakai yang mana. Ini bisa kamu tambahkan di &lt;strong&gt;App.css&lt;/strong&gt;  ya.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* HTML: &amp;lt;div class="loader"&amp;gt;&amp;lt;/div&amp;gt; */
.loader {
  width: fit-content;
  font-weight: bold;
  font-family: sans-serif;
  font-size: 30px;
  padding-bottom: 8px;
  background: linear-gradient(currentColor 0 0) 0 100%/0% 3px no-repeat;
  animation: l2 2s linear infinite;
}
.loader:before {
  content:"Loading..."
}
@keyframes l2 {to{background-size: 100% 3px}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ashiap, sekarang mau coba? Belum. Jangan lupa tambahkan environment variable-nya. Bisa membuat file .env lalu masukkan nilai API Key-nya.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_API_KEY=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isi dengan key kamu ya.&lt;/p&gt;

&lt;p&gt;Terus, terus? Yuk cobain lagi.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdctr3k3a0n8k0dnnkf0q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdctr3k3a0n8k0dnnkf0q.png" width="632" height="597"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Cuaca Sekarang&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ini cuacaku. Bagiamana cuaca kamu?&lt;/p&gt;

&lt;h3&gt;
  
  
  Aplikasinya?
&lt;/h3&gt;

&lt;p&gt;Saya sematkan di sini ya.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/berviantoleo/open-weather-exploration/" rel="noopener noreferrer"&gt;GitHub - berviantoleo/open-weather-exploration: Open Weather Example&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Penutup
&lt;/h3&gt;

&lt;p&gt;Terima kasih ya sudah membaca. Salam sejathera untuk kita semua. Semoga bermanfaat. Jika ada tanggapan, jangan sungkan. *Chheeeersss!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2ATQUW5nTHLZzVbgxo" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2ATQUW5nTHLZzVbgxo" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Andre Hunter on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>geolocation</category>
      <category>axios</category>
      <category>react</category>
      <category>openweatherapi</category>
    </item>
    <item>
      <title>Exploring .NET Aspire and Adding it to my existing boilerplate</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Sat, 05 Apr 2025 04:45:00 +0000</pubDate>
      <link>https://dev.to/berviantoleo/exploring-net-aspire-and-adding-it-to-my-existing-boilerplate-40bb</link>
      <guid>https://dev.to/berviantoleo/exploring-net-aspire-and-adding-it-to-my-existing-boilerplate-40bb</guid>
      <description>&lt;p&gt;Hi everyone!&lt;/p&gt;

&lt;p&gt;Glad to see you again!&lt;/p&gt;

&lt;p&gt;I'm coming up with a new topic, which is still regarding DevOps. Yes, as your guest, it's .NET Aspire!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5vfacz9g7ip0hlhlhds.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5vfacz9g7ip0hlhlhds.gif" alt="Happy GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don't want to take too long for the introduction. Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/get-started/build-your-first-aspire-app?pivots=visual-studio#prerequisites" rel="noopener noreferrer"&gt;.NET Aspire Prerequisite&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;.NET 9.0&lt;/li&gt;
&lt;li&gt;Docker (You may use Podman)&lt;/li&gt;
&lt;li&gt;JetBrains Rider or Your Favourite IDE&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/bervProject/NETCoreAPIBoilerplate" rel="noopener noreferrer"&gt;My Existing Project&lt;/a&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Note: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I will use JetBrains Rider. So, I will install the .NET Aspire Plugin for JetBrains Rider.&lt;/li&gt;
&lt;li&gt;Another &lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/get-started/add-aspire-existing-app?tabs=windows&amp;amp;pivots=dotnet-cli" rel="noopener noreferrer"&gt;reference&lt;/a&gt; for adding .NET Aspire to the existing project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup .NET Aspire Project
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5vrcscpftj3cngpiibm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5vrcscpftj3cngpiibm.gif" alt="Ready GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ensure you already have .NET Aspire templates; if not, please install them using this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new &lt;span class="nb"&gt;install &lt;/span&gt;Aspire.ProjectTemplates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Create a .NET Aspire AppHost project through .NET Aspire templates.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new aspire-apphost &lt;span class="nt"&gt;-f&lt;/span&gt; net9.0 &lt;span class="nt"&gt;--name&lt;/span&gt; BervProject.WebApi.Boilerplate.AppHost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fic3o3rc9upyqc5rp2a9o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fic3o3rc9upyqc5rp2a9o.png" alt=".NET Aspire AppHost Successfully created"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, create a .NET Aspire Service Defaults project through .NET Aspire templates.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new aspire-servicedefaults &lt;span class="nt"&gt;-f&lt;/span&gt; net9.0 &lt;span class="nt"&gt;--name&lt;/span&gt; BervProject.WebApi.Boilerplate.ServiceDefaults
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8m7zw6qysofqp4bwiobd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8m7zw6qysofqp4bwiobd.png" alt=".NET Aspire Service Defaults Successfully created"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's add the projects to our solutions.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet sln add BervProject.WebApi.Boilerplate.AppHost/BervProject.WebApi.Boilerplate.AppHost.csproj BervProject.WebApi.Boilerplate.ServiceDefaults/BervProject.WebApi.Boilerplate.ServiceDefaults.csproj
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Our project solutions will be like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6o7144r1e74zmwo4b064.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6o7144r1e74zmwo4b064.png" alt="Project Solutions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well done! Now, let's integrate the existing Web API and add some required services.&lt;/p&gt;
&lt;h2&gt;
  
  
  Integrating the Web API
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add the Web API as a reference in our AppHost.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; dotnet add BervProject.WebApi.Boilerplate.AppHost reference BervProject.WebApi.Boilerplate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add Redis package to AppHost.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add BervProject.WebApi.Boilerplate.AppHost package Aspire.Hosting.Redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add Postgres package to AppHost.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add BervProject.WebApi.Boilerplate.AppHost package Aspire.Hosting.PostgreSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add Azure Storage package to AppHost.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add BervProject.WebApi.Boilerplate.AppHost package Aspire.Hosting.Azure.Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add Azure Service Bus package to AppHost.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add BervProject.WebApi.Boilerplate.AppHost package Aspire.Hosting.Azure.ServiceBus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Adding Migration Service
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Creating the migration service.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new worker &lt;span class="nt"&gt;-n&lt;/span&gt; BervProject.WebApi.Boilerplate.MigrationService &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"net9.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add to the solution.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet sln add BervProject.WebApi.Boilerplate.MigrationService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add reference to the API (the source of the migration data)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add BervProject.WebApi.Boilerplate.MigrationService reference BervProject.WebApi.Boilerplate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add reference to the service defaults.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add BervProject.WebApi.Boilerplate.MigrationService reference BervProject.WebApi.Boilerplate.ServiceDefaults
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;Aspire.Npgsql.EntityFrameworkCore.PostgreSQL&lt;/code&gt; package to the migration service.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add BervProject.WebApi.Boilerplate.MigrationService package Aspire.Npgsql.EntityFrameworkCore.PostgreSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Update the &lt;code&gt;Program.cs&lt;/code&gt; in the migration service.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-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;BervProject.WebApi.Boilerplate.EntityFramework&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BervProject.WebApi.Boilerplate.MigrationService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateApplicationBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddServiceDefaults&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddHostedService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;AddOpenTelemetry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithTracing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tracing&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActivitySourceName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddNpgsqlDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BoilerplateDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"BoilerplateConnectionString"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Update the &lt;code&gt;Worker.cs&lt;/code&gt; in the migration service.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-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;System.Diagnostics&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BervProject.WebApi.Boilerplate.EntityFramework&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.EntityFrameworkCore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;BervProject.WebApi.Boilerplate.MigrationService&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;class&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BackgroundService&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;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ActivitySourceName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Migrations"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ActivitySource&lt;/span&gt; &lt;span class="n"&gt;SActivitySource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ActivitySourceName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;_serviceProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IHostApplicationLifetime&lt;/span&gt; &lt;span class="n"&gt;_hostApplicationLifetime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;IHostApplicationLifetime&lt;/span&gt; &lt;span class="n"&gt;hostApplicationLifetime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_serviceProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_hostApplicationLifetime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hostApplicationLifetime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ExecuteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;activity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SActivitySource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Migrating database"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ActivityKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dbContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServiceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BoilerplateDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;RunMigrationAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;activity&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;AddException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;_hostApplicationLifetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StopApplication&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;RunMigrationAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BoilerplateDbContext&lt;/span&gt; &lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateExecutionStrategy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&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="c1"&gt;// Run migration in a transaction to avoid partial migration if it fails.&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MigrateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cancellationToken&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;ul&gt;
&lt;li&gt;Add the Migration Service to the AppHost.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add BervProject.WebApi.Boilerplate.AppHost reference BervProject.WebApi.Boilerplate.MigrationService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;Microsoft.EntityFrameworkCore&lt;/code&gt; to both BervProject.WebApi.Boilerplate.MigrationService and BervProject.WebApi.Boilerplate projects to avoid package version conflicts.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.EntityFrameworkCore"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"9.0.3"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;

&lt;h3&gt;
  
  
  Final Changes
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F18pygpbey9489hkynizd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F18pygpbey9489hkynizd.gif" alt="Finally GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update the Program.cs in our AppHost.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DistributedApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRedis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cache"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;WithRedisInsight&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPostgres&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;WithPgAdmin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;postgresdb&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgresdb"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceBus&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAzureServiceBus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"messaging"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;RunAsEmulator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAzureStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"storage"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;RunAsEmulator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;blobs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddBlobs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"blobs"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;queues&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddQueues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"queues"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tables&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTables&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tables"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;migration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddProject&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BervProject_WebApi_Boilerplate_MigrationService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"migrations"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;postgresdb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;connectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"BoilerplateConnectionString"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithExplicitStart&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddProject&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BervProject_WebApi_Boilerplate&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"apiservice"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithHttpEndpoint&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;connectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Redis"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;postgresdb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;connectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"BoilerplateConnectionString"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blobs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;connectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"AzureStorageBlob"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queues&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;connectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"AzureStorageQueue"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tables&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;connectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"AzureStorageTable"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceBus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;connectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"AzureServiceBus"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WaitFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WaitFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;postgresdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WaitFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blobs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WaitFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queues&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WaitFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tables&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WaitFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceBus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WaitForCompletion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;migration&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;

&lt;h3&gt;
  
  
  Migrating Connection Strings in the existing API
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Update &lt;code&gt;Program.cs&lt;/code&gt; in &lt;code&gt;BervProject.WebApi.Boilerplate&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-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;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Reflection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Autofac.Extensions.DependencyInjection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BervProject.WebApi.Boilerplate.ConfigModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BervProject.WebApi.Boilerplate.EntityFramework&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BervProject.WebApi.Boilerplate.Extenstions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BervProject.WebApi.Boilerplate.Services&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BervProject.WebApi.Boilerplate.Services.Azure&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Hangfire&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Hangfire.PostgreSql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Builder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.EntityFrameworkCore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.DependencyInjection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Hosting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Logging&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;NLog.Web&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseServiceProviderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AutofacServiceProviderFactory&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ClearProviders&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetMinimumLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LogLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddNLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Nlog.config"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddNLogWeb&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseNLog&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// settings injection&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;awsConfig&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AWSConfiguration&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;awsConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;azureConfig&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Azure"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AzureConfiguration&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;azureConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// aws services&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;SetupAWS&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// azure services&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;SetupAzure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// cron services&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ICronService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CronService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;AddHangfire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UsePostgreSqlStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseNpgsqlConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"BoilerplateConnectionString"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;AddHangfireServer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// essential services&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;AddStackExchangeRedisCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Redis"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BoilerplateDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseNpgsql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"BoilerplateConnectionString"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;AddHealthChecks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;AddControllers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;AddApiVersioning&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&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;AddSwaggerGen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;xmlFilename&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetExecutingAssembly&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;GetName&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.xml"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IncludeXmlComments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xmlFilename&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// register Consumer&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;connectionString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AzureServiceBus"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;queueName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;azureConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServiceBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueueName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;topicName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;azureConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServiceBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TopicName&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queueName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bus&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IServiceBusQueueConsumer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RegisterOnMessageHandlerAndReceiveMessages&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topicName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bus&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IServiceBusTopicSubscription&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RegisterOnMessageHandlerAndReceiveMessages&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// register essential things&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseDeveloperExceptionPage&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="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseExceptionHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseRouting&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthorization&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapHealthChecks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/healthz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSwagger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RouteTemplate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"api/docs/{documentName}/swagger.json"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSwaggerUI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SwaggerEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/docs/v1/swagger.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"My API V1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RoutePrefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"api/docs"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapControllers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapHangfireDashboard&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&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;ul&gt;
&lt;li&gt;Update &lt;code&gt;SetupAzureExtension.cs&lt;/code&gt; in &lt;code&gt;BervProject.WebApi.Boilerplate&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-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;Microsoft.Extensions.Configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;BervProject.WebApi.Boilerplate.Extenstions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BervProject.WebApi.Boilerplate.Services.Azure&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.DependencyInjection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Azure&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;class&lt;/span&gt; &lt;span class="nc"&gt;SetupAzureExtension&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;SetupAzure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&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="n"&gt;ConfigurationManager&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&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;AddAzureClients&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddBlobServiceClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AzureStorageBlob"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddQueueServiceClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AzureStorageQueue"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddServiceBusClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AzureServiceBus"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTableServiceClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AzureStorageTable"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IAzureQueueServices&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AzureQueueServices&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ITopicServices&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TopicServices&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IAzureStorageQueueService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AzureStorageQueueService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IBlobService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BlobService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// add each tables&lt;/span&gt;
        &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IAzureTableStorageService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;AzureTableStorageService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// service bus&lt;/span&gt;
        &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IServiceBusQueueConsumer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ServiceBusQueueConsumer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IServiceBusTopicSubscription&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ServiceBusTopicSubscription&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IProcessData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ProcessData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&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;AddApplicationInsightsTelemetry&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;
  
  
  Running the AppHost
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hfix5dfb5rxoq13nhw8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hfix5dfb5rxoq13nhw8.gif" alt="Sweat GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's run the AppHost!&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet run &lt;span class="nt"&gt;--project&lt;/span&gt; .&lt;span class="se"&gt;\B&lt;/span&gt;ervProject.WebApi.Boilerplate.AppHost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Please wait until all services are running. It may take a long time, depending on your network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03evpbsuj6x00g66m2qd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03evpbsuj6x00g66m2qd.png" alt="Successfully Running Services"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before starting the API, please run the &lt;code&gt;migration&lt;/code&gt; service first after the &lt;code&gt;postgres&lt;/code&gt; service is running. When there are no errors, your API will run successfully.&lt;/p&gt;
&lt;h2&gt;
  
  
  Let's Compare It with the PR
&lt;/h2&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/bervProject/NETCoreAPIBoilerplate/pull/2827" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        feat: Add .NET Aspire
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#2827&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/berviantoleo" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F15927349%3Fv%3D4" alt="berviantoleo avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/berviantoleo" rel="noopener noreferrer"&gt;berviantoleo&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/bervProject/NETCoreAPIBoilerplate/pull/2827" rel="noopener noreferrer"&gt;&lt;time&gt;Apr 05, 2025&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      
    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/bervProject/NETCoreAPIBoilerplate/pull/2827" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Try the API
&lt;/h2&gt;

&lt;p&gt;You may try the API with a health check endpoint &lt;code&gt;/healthz&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgp4vqe16sdt99vwouyni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgp4vqe16sdt99vwouyni.png" alt="Health Endpoint"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkcuk5wf3ryb7inctjij.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkcuk5wf3ryb7inctjij.gif" alt="Tired GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gosh! So tired, it's quite many things that I need to set up for the first time. However, it's satisfying! I notice some unexpected behaviour, for example, the migrating service won't stop after it's finished migrating, especially when running automatically. So, I use a workaround by starting it manually.&lt;/p&gt;

&lt;p&gt;That's it. If you have any feedback, please let me know!&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm15uv706ds8sbdus2bcl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm15uv706ds8sbdus2bcl.gif" alt="Love GIF"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>devops</category>
      <category>programming</category>
      <category>docker</category>
    </item>
    <item>
      <title>Exploring Azure Queue Storage in .NET</title>
      <dc:creator>Bervianto Leo Pratama</dc:creator>
      <pubDate>Sat, 05 Oct 2024 08:52:44 +0000</pubDate>
      <link>https://dev.to/berviantoleo/exploring-azure-queue-storage-in-net-55mk</link>
      <guid>https://dev.to/berviantoleo/exploring-azure-queue-storage-in-net-55mk</guid>
      <description>&lt;h2&gt;
  
  
  Preparation
&lt;/h2&gt;

&lt;p&gt;There are some steps we need to take.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Azurite.&lt;/li&gt;
&lt;li&gt;Set up the Projects.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Install Azurite
&lt;/h3&gt;

&lt;p&gt;You may follow this &lt;a href="https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&amp;amp;bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json&amp;amp;tabs=visual-studio%2Cblob-storage" rel="noopener noreferrer"&gt;tutorial page&lt;/a&gt; to install Azurite. We will Azurite as our testing when developing the application which uses Azure Queue Storage. We won't use Azure Queue Storage directly but use the simulator. Feel free to use any method that you want. I will cover how to use the emulator in Docker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up the projects
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create the solution file. &lt;code&gt;dotnet new sln&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create the "Producer" project. &lt;code&gt;dotnet new console -o Producer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create the "Consumer" project. &lt;code&gt;dotnet new console -o Consumer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add both projects to the solution file. &lt;code&gt;dotnet sln add Consumer Producer&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prepare the Producer
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add the &lt;code&gt;Azure.Storage.Queues&lt;/code&gt; package to the Producer project. &lt;code&gt;dotnet add Producer package Azure.Storage.Queues&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You may wonder how to authenticate or access the Azure Storage Queue. Please refer to this &lt;a href="https://learn.microsoft.com/en-us/azure/storage/queues/storage-quickstart-queues-dotnet?tabs=passwordless%2Croles-azure-portal%2Cenvironment-variable-windows%2Csign-in-visual-studio-code" rel="noopener noreferrer"&gt;page&lt;/a&gt; for more information. Since we use Azurite, we may use the connection string. Please use Microsoft's recommended authentication to use the code in production. Please write these codes to create the Queue Client and send the message.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prepare the Consumer
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add the &lt;code&gt;Azure.Storage.Queues&lt;/code&gt; package to the Producer project. &lt;code&gt;dotnet add Producer package Azure.Storage.Queues&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Please write these codes to create the Queue Client and receive the message.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/CzCX3OxMmYo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Extra (Using Docker)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Write a Dockerfile for each application. Save each Dockerfile as "Dockerfile" without a double quote in each application directory.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write a &lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Please ensure the connection string becomes like this. &lt;code&gt;string connectionString = "DefaultEndpointsProtocol=https;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;QueueEndpoint=http://azurite:10001/devstoreaccount1;";&lt;br&gt;
&lt;/code&gt; We need to set the address to become the Azurite service name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build the images. &lt;code&gt;docker compose build&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the compose. &lt;code&gt;docker compose up&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/iXsPt07TjF8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/berviantoleo" rel="noopener noreferrer"&gt;
        berviantoleo
      &lt;/a&gt; / &lt;a href="https://github.com/berviantoleo/AzureStorageQueue" rel="noopener noreferrer"&gt;
        AzureStorageQueue
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Azure Storage Queue&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Sample App for Tutorial in my dev.to&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;LICENSE&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;MIT&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/berviantoleo/AzureStorageQueue" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;You need to ensure the messages are cleared after processing the message. You may use the queue to send a small JSON message. Ensure the message is not more than 64 KB.&lt;/p&gt;

&lt;p&gt;Many use cases are using Azure Storage Queue. For example, we have e-commerce that consists of many microservices. We have a service that receives an order message from the customer. Order service will send the message into the queue and stock service will receive the message and ensure those goods are locked to the customer. The processes are asynchronous. &lt;/p&gt;

&lt;p&gt;Do you have any suggestions? Feel free to comment here. Thank you for reading.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftu2lzcxw4kgugcp0asl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftu2lzcxw4kgugcp0asl.gif" alt="Sesame happy GIF" width="400" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>azure</category>
      <category>tutorial</category>
      <category>azurequeue</category>
    </item>
  </channel>
</rss>
