<?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: Thanh Ba Nguyen</title>
    <description>The latest articles on DEV Community by Thanh Ba Nguyen (@btnguyen2k).</description>
    <link>https://dev.to/btnguyen2k</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%2F1084865%2Fe5d35f86-066e-4648-8a42-f975c23ed77e.jpeg</url>
      <title>DEV Community: Thanh Ba Nguyen</title>
      <link>https://dev.to/btnguyen2k</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/btnguyen2k"/>
    <language>en</language>
    <item>
      <title>Host your website on Azure, for free</title>
      <dc:creator>Thanh Ba Nguyen</dc:creator>
      <pubDate>Sat, 27 May 2023 16:34:47 +0000</pubDate>
      <link>https://dev.to/btnguyen2k/host-your-website-on-azure-for-free-lo0</link>
      <guid>https://dev.to/btnguyen2k/host-your-website-on-azure-for-free-lo0</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://mpn.btnguyen2k.me/cms/cloud/azure-host-website-free/?l=en"&gt;my personal notes&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://azure.microsoft.com/"&gt;Azure&lt;/a&gt; is a cloud computing platform operated by Microsoft. Azure offers a range of services that are free for the initial 12 months, as well as a selection of always free services&lt;sup&gt;[*]&lt;/sup&gt;. This post explores those services that are always free at Azure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web application hosting
&lt;/h2&gt;

&lt;p&gt;Azure offers quite a few free services&lt;sup&gt;[*]&lt;/sup&gt; that can be used to host your website:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://azure.microsoft.com/pricing/details/app-service/linux/"&gt;&lt;strong&gt;Azure App Service&lt;/strong&gt;&lt;/a&gt;: free with &lt;strong&gt;F1&lt;/strong&gt; tier, &lt;em&gt;1Gb RAM, 1Gb storage, 10 web apps, 60 CPU-minutes per day&lt;/em&gt;. Support Windows and Linux, the website can be deployed as a binary package or container.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://azure.microsoft.com/pricing/details/container-apps/"&gt;&lt;strong&gt;Azure Container Apps&lt;/strong&gt;&lt;/a&gt;: monthly free of &lt;em&gt;180,000 vCPU-seconds, 360,000 GiB Memory-seconds and 2 million requests&lt;/em&gt; with &lt;strong&gt;Consumption&lt;/strong&gt; plan. The website can be deployed as a container.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://azure.microsoft.com/pricing/details/functions/"&gt;&lt;strong&gt;Azure Functions&lt;/strong&gt;&lt;/a&gt;: monthly free of 1 million requests and 400,000 GB resource-seconds with &lt;strong&gt;Consumption&lt;/strong&gt; plan. The website can be deployed as a binary packages or container.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;➡️ While Azure Functions may not be the optimal choice for hosting a website, it remains well-suited for &lt;em&gt;web API applications&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;⚠️ The &lt;em&gt;Consumption&lt;/em&gt; plan does not support the deployment of applications as &lt;em&gt;containers&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;⚠️ A storage account is created by default with each Functions app. The storage account is &lt;em&gt;not included&lt;/em&gt; in the free grant. However, the associated cost is relatively small.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Database
&lt;/h2&gt;

&lt;p&gt;In scenarios where your website requires database storage, Azure allows &lt;em&gt;one free Cosmos DB account per subsciprtion&lt;/em&gt;, which includes 1000 RU/s and 25Gb storage capacity at no cost.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://azure.microsoft.com/pricing/details/cosmos-db/"&gt;&lt;strong&gt;Azure Cosmos DB&lt;/strong&gt;&lt;/a&gt; is a NoSQL service available on Azure. It provides compatibility with MongoDB clients, making it a convenient drop-in replacement if your website relies on MongoDB.&lt;/p&gt;

&lt;p&gt;For further information about the free tier of Cosmos DB, please refer to &lt;a href="https://learn.microsoft.com/azure/cosmos-db/free-tier"&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other components
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://azure.microsoft.com/pricing/details/bandwidth/"&gt;&lt;strong&gt;Bandwidth&lt;/strong&gt;&lt;/a&gt;: Azure &lt;em&gt;does not charge ingress data&lt;/em&gt; and the &lt;em&gt;first 100Gb of egress data monthly&lt;/em&gt; is free&lt;sup&gt;[*]&lt;/sup&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;It is important to note that the free 100GB egress data allowance is calculated based on all workloads deployed within the Azure subscription, not per individual application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://hub.docker.com/"&gt;Docker Hub&lt;/a&gt;&lt;/strong&gt;: if your website is deployed as a container, it will require a service to &lt;em&gt;host images&lt;/em&gt;. The &lt;a href="https://azure.microsoft.com/pricing/details/container-registry/"&gt;Azure Container Registry&lt;/a&gt; service offers &lt;em&gt;100GB of free storage for the first 12 months&lt;/em&gt;&lt;sup&gt;[*]&lt;/sup&gt;. However, since this post focuses on always free services, we will exclude Azure Container Registry from the list. As an alternative, you can utilize Docker Hub for the same purpose&lt;sup&gt;[-]&lt;/sup&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom domain&lt;/strong&gt;: once your website is deployed on an Azure service, users can access it through a URL like &lt;a href="https://mpn.whiteisland-8603b684.australiaeast.azurecontainerapps.io"&gt;https://mpn.whiteisland-8603b684.australiaeast.azurecontainerapps.io&lt;/a&gt;. However, this URL may not appear visually appealing. Fortunately, several Azure services enable you to associate a custom domain with your website at no cost. For instance, your website hosted on Azure can have a URL such as &lt;a href="https://mpn.btnguyen2k.me"&gt;https://mpn.btnguyen2k.me&lt;/a&gt;. Please note that you will need to purchase the domain name separately.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Before we wrap up
&lt;/h2&gt;

&lt;p&gt;Azure demonstrates its generosity by providing a range of always free services that are well-suited for hosting personal websites or hobby projects. Additionally, you have the option to leverage free services offered by other providers, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The MongoDB free tier available through &lt;a href="https://www.mongodb.com/atlas"&gt;MongoDB Atlas&lt;/a&gt;&lt;sup&gt;[-]&lt;/sup&gt;, which offers 500GB of free storage, can be a replacement for Azure Cosmos DB.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cloudflare.com/"&gt;CloudFlare&lt;/a&gt;'s free tier&lt;sup&gt;[-]&lt;/sup&gt; can be used to cache your website content and reduce bandwidth consumption.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;[*] For a completed list of Azure's free services, refer to &lt;a href="https://azure.microsoft.com/pricing/free-services/"&gt;this link&lt;/a&gt;. Kindly be aware that Azure retains the right to modify their policies and offerings at any given time. The information provided in this post is accurate as of its publication date and is intended for informational purposes only.&lt;/p&gt;

&lt;p&gt;[**] Azure Cosmos DB automatically make backups of your database and retains them free of charge for a period of 7 days. However, additional costs may apply if you wish to retain the backups for an extended duration.&lt;/p&gt;

&lt;p&gt;[-] Kindly be aware that service providers retains the right to modify their policies and offerings at any given time. The information provided in this post is accurate as of its publication date and is intended for informational purposes only.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>azure</category>
      <category>free</category>
      <category>hosting</category>
    </item>
    <item>
      <title>Go database/sql driver for AWS DynamoDB</title>
      <dc:creator>Thanh Ba Nguyen</dc:creator>
      <pubDate>Sat, 27 May 2023 16:18:02 +0000</pubDate>
      <link>https://dev.to/btnguyen2k/go-databasesql-driver-for-aws-dynamodb-3pj1</link>
      <guid>https://dev.to/btnguyen2k/go-databasesql-driver-for-aws-dynamodb-3pj1</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://mpn.btnguyen2k.me/cms/programming/go-golang-dynamodb-sql/?l=en"&gt;my personal notes&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/dynamodb/"&gt;Amazon DynamoDB&lt;/a&gt; is a fully managed NoSQL database service provided by Amazon as part of the Amazon Web Services (AWS) portfolio.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS offers the &lt;a href="https://github.com/aws/aws-sdk-go-v2"&gt;SDK for Go&lt;/a&gt;, which facilitates seamless integration between Go applications and various AWS services, including DynamoDB.&lt;/li&gt;
&lt;li&gt;AWS provides users with the flexibility to utilize &lt;a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html#ql-reference.what-is"&gt;PartiQL&lt;/a&gt;, a SQL-like query language, for efficient manipulation of DynamoDB items via operations such as &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;, and &lt;code&gt;DELETE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The Go programming language includes the &lt;a href="https://pkg.go.dev/database/sql"&gt;&lt;code&gt;database/sql&lt;/code&gt; package&lt;/a&gt;, which offers a versatile and standardized interface for interacting with SQL databases or databases that support SQL-like functionality. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To establish a seamless integration between the three components mentioned earlier, an essential component is required: a database driver that enables Go applications to interface with DynamoDB using the standard &lt;code&gt;database/sql&lt;/code&gt; package. This article introduces &lt;a href="https://github.com/btnguyen2k/godynamo"&gt;godynamo&lt;/a&gt; - a &lt;code&gt;database/sql&lt;/code&gt; driver for AWS DynamoDB.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I am the author of &lt;a href="https://github.com/btnguyen2k/godynamo"&gt;godynamo&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Utilizing &lt;a href="https://github.com/btnguyen2k/godynamo"&gt;godynamo&lt;/a&gt; to interact with AWS DynamoDB follows a familiar pattern akin to employing any &lt;code&gt;database/sql&lt;/code&gt; driver for a database system, for example MySQL. The process involves a sequence of steps: first, importing the &lt;a href="https://github.com/btnguyen2k/godynamo"&gt;godynamo&lt;/a&gt; driver into the project; next, initializing a &lt;code&gt;sql.DB&lt;/code&gt; instance through using the &lt;code&gt;sql.Open(...)&lt;/code&gt; function; and lastly, leveraging SQL statements to operate on the items within the DynamoDB table via the &lt;code&gt;sql.DB&lt;/code&gt; instance.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"database/sql"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"github.com/btnguyen2k/gocosmos"&lt;/span&gt; &lt;span class="c"&gt;// import driver&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// build connection string&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"godynamo"&lt;/span&gt;
    &lt;span class="n"&gt;dsn&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Region=us-east-1;AkId=aws-access-key-id;SecretKey=aws-secret-key"&lt;/span&gt;
    &lt;span class="c"&gt;// create the sql.DB instance&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dsn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// use SQL statement via the sql.DB instance&lt;/span&gt;
    &lt;span class="n"&gt;dbrows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`LIST TABLES`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;dbRows&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dbRows&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&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;h2&gt;
  
  
  Supported SQL statements
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/btnguyen2k/godynamo"&gt;godynamo&lt;/a&gt; supports 3 groups of SQL statements: &lt;em&gt;table&lt;/em&gt;, &lt;em&gt;index&lt;/em&gt; and &lt;em&gt;document&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Table-related statement:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;CREATE TABLE&lt;/code&gt;: create a new DynamoDB table.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;LIST TABLES&lt;/code&gt;: list all available tables.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;DESCRIBE TABLE&lt;/code&gt;: return info of a table.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;ALTER TABLE&lt;/code&gt;: change a table's RCU/WCU or table-class.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;DROP TABLE&lt;/code&gt;: remove an existing table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Index-related statements:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;DESCRIBE LSI&lt;/code&gt;: return info of a &lt;code&gt;Local Secondary Index&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;CREATE GSI&lt;/code&gt;: create a new &lt;code&gt;Global Secondary Index&lt;/code&gt; on a table.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;DESCRIBE GSI&lt;/code&gt;: return info of a &lt;code&gt;Global Secondary Index&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;ALTER GSI&lt;/code&gt;: change RCU/WCU settings of a &lt;code&gt;Global Secondary Index&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;DROP GSI&lt;/code&gt;: remove an existing &lt;code&gt;Global Secondary Index&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Document-related statements:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;INSERT&lt;/code&gt;: add an item to a table.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;SELECT&lt;/code&gt;: retrieve data from a table.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;UPDATE&lt;/code&gt;: modify the value of one or more attributes within an item in a table.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;DELETE&lt;/code&gt;: delete an existing item from a table.&lt;/p&gt;

&lt;p&gt;Find more details on godynamo repository: &lt;a href="https://github.com/btnguyen2k/godynamo"&gt;https://github.com/btnguyen2k/godynamo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>go</category>
      <category>dynamodb</category>
      <category>driver</category>
    </item>
  </channel>
</rss>
