<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sainath Ramanathan</title>
    <description>The latest articles on Forem by Sainath Ramanathan (@rksainath).</description>
    <link>https://forem.com/rksainath</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%2F49427%2Fb61c16dd-87e6-4d84-a9f2-0360d55c11b0.jpg</url>
      <title>Forem: Sainath Ramanathan</title>
      <link>https://forem.com/rksainath</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rksainath"/>
    <language>en</language>
    <item>
      <title>Empty phone number field validation using yup-phone</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Sat, 08 Oct 2022 08:42:19 +0000</pubDate>
      <link>https://forem.com/rksainath/empty-phone-number-field-validation-using-yup-phone-34h5</link>
      <guid>https://forem.com/rksainath/empty-phone-number-field-validation-using-yup-phone-34h5</guid>
      <description>&lt;p&gt;I recently encountered an issue while using the library &lt;a href="https://github.com/abhisekp/yup-phone"&gt;yup-phone&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;yup-phone is a react-library that can be used to validate phone numbers entered in the form field. It uses google-libphonenumber to validate any given phone number in the input field.&lt;/p&gt;

&lt;p&gt;Sample usage of yup-phone is given below,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const validationSchema = Yup.object().shape({
    mobile: Yup.string().phone()
})

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

&lt;/div&gt;



&lt;p&gt;The above schema validates if the given number is a valid phone number format or not. You can read in detail about its usage on the &lt;a href="https://github.com/abhisekp/yup-phone/blob/master/docs/index.md"&gt;official page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The problem with the above snippet is it makes the form submission mandatory to provide a phone number even if it is not required. If the field is left empty the validation is made against the empty field. Yup methods &lt;code&gt;optional&lt;/code&gt; and &lt;code&gt;notRequired&lt;/code&gt; didn't work either. ( &lt;strong&gt;&lt;em&gt;Note: This error is not resolved by yup-phone at the time of writing this post. Please check the official page for tracking the issue.&lt;/em&gt;&lt;/strong&gt; )&lt;/p&gt;

&lt;p&gt;Here is a workaround to fix the empty field validation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const validationSchema = Yup.object().shape({
        mobile: Yup.string().when('mobile', {
            is: (value) =&amp;gt; value?.length &amp;gt; 0,
            then: Yup.string().phone(),
            otherwise: Yup.string(),
        }),
    },
    [
        ['mobile', 'mobile']
    ]
)

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

&lt;/div&gt;



&lt;p&gt;Note that the mobile property is written twice in the list of dependencies. This is to avoid cyclic dependency errors as explained in the StackOverflow &lt;a href="https://stackoverflow.com/a/67629576"&gt;post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Below is the code snippet for multiple phone number fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const validationSchema = Yup.object().shape({
        mobile: Yup.string().when('mobile', {
            is: (value) =&amp;gt; value?.length &amp;gt; 0,
            then: Yup.string().phone(),
            otherwise: Yup.string(),
        }),
        phone: Yup.string().when('phone', {
            is: (value) =&amp;gt; value?.length &amp;gt; 0,
            then: Yup.string().phone(),
            otherwise: Yup.string(),
        }),
    },
    [
        ['mobile', 'mobile'],
        ['phone', 'phone']
    ]
)

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Official page for yup-phone: &lt;a href="https://github.com/abhisekp/yup-phone"&gt;https://github.com/abhisekp/yup-phone&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Issue: &lt;a href="https://github.com/abhisekp/yup-phone/issues/313"&gt;https://github.com/abhisekp/yup-phone/issues/313&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>yup</category>
      <category>yupphone</category>
    </item>
    <item>
      <title>The Great Merge</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Fri, 16 Sep 2022 11:42:17 +0000</pubDate>
      <link>https://forem.com/rksainath/the-great-merge-43bb</link>
      <guid>https://forem.com/rksainath/the-great-merge-43bb</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Ethereum is the largest blockchain network next to Bitcoin. It is evolving a lot and equally competing with Bitcoin. Ethereum has paved the way for so many blockchains like &lt;a href="https://solana.com/"&gt;Solana&lt;/a&gt;, &lt;a href="https://polygon.technology/"&gt;Polygon&lt;/a&gt;, and &lt;a href="https://cardano.org/"&gt;Cardano&lt;/a&gt; that try to solve the problems and limitations of Ethereum. The following diagram shows the size of the Bitcoin vs Ethereum blockchain. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v0qYUcoA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.bitmex.com/wp-content/uploads/2021/11/ethbtcsize-1024x605.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v0qYUcoA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.bitmex.com/wp-content/uploads/2021/11/ethbtcsize-1024x605.png" alt="Bitcoin vs Ethereum Blockchain size" width="880" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A Quick History
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p8QG77Bk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.forbes.com/advisor/wp-content/uploads/2021/03/ethereum-1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p8QG77Bk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.forbes.com/advisor/wp-content/uploads/2021/03/ethereum-1.jpeg" alt="ethereum" width="880" height="495"&gt;&lt;/a&gt;Ethereum was created with the idea of a permissionless blockchain back in 2015 with Proof-of-Work (PoW) as its consensus mechanism. Until then people have known blockchain only as a cryptocurrency but Ethereum changed it with a plethora of use cases like digital assets, supply chain tracking, etc by leveraging smart contracts and ETH tokens which was famously called a 'gas fee' to validate a transaction which was then paid to the validators in the network for Proof-of-Work done.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consensus Mechanism
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GBY6aoFP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://content-hub-static.crypto.com/static/4437c0842e44534320e525e26150dce7/87baf/Consensus-Mechanisms-in-Blockchain-infographic-01-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GBY6aoFP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://content-hub-static.crypto.com/static/4437c0842e44534320e525e26150dce7/87baf/Consensus-Mechanisms-in-Blockchain-infographic-01-1.png" alt="consensus" width="880" height="880"&gt;&lt;/a&gt;Ethereum has many networks for development, testing, and production use cases. 'Ethereum Mainnet' was the primary public Ethereum production blockchain based on the consensus mechanism of Proof-of-Work (PoW).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Proof-of-Work(PoW) is hardware intensive and not eco-friendly as several miners participate using expensive resources in validating the block.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proof-of-Stake (PoS) lets a validator participate in the Ethereum network by staking the ETH which is more scalable, energy-efficient, secure, and has a lower barrier to entry than PoW.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Evolution of Beacon Chain
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cdgBNnnV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://finematics.com/wp-content/uploads/2020/12/pow-pos-1024x431.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cdgBNnnV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://finematics.com/wp-content/uploads/2020/12/pow-pos-1024x431.png" alt="beacon-chain" width="880" height="370"&gt;&lt;/a&gt;In recent years, Web3 gave birth to a lot of products like Decentralized Finance(DeFi), Non-Fungible Tokens (NFT), etc. Networks have to come up with speed and energy efficiency to serve the purpose and maximize the adoption of blockchain. Ethereum launched Beacon Chain based on PoS in late 2020 parallel to the existing Mainnet to slowly replace it with a single consensus i.e the PoS. The Ethereum team knew that PoW won't be good enough for the long run and decided to merge it with the Mainnet.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Merger
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tUa0HtLz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663327131642/abRGbPpcX.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tUa0HtLz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663327131642/abRGbPpcX.png" alt="ethereum-merge.png" width="880" height="373"&gt;&lt;/a&gt;Ethereum Mainnet merged with Beacon Chain on September 15, 2022. As Mainnet merged with the Beacon Chain, it also merged the entire transactional history of Ethereum. Mining is no longer the means of producing valid blocks in Ethereum. Going forward, the Beacon Chain is the engine of block production. The merger led the Beacon Chain to accept transactions from the original Ethereum chain, bundle them into blocks, and then organize them into a blockchain using a proof-of-stake-based consensus mechanism.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terminology change
&lt;/h3&gt;

&lt;p&gt;The term Eth2 has been deprecated. There is nothing called Ethereum 2.0. The new terminologies for Ethereum are as followed,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eth1 - Execution Layer&lt;/li&gt;
&lt;li&gt;Eth2 - Consensus Layer&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Execution Layer + Consensus Layer -&amp;gt; ETHEREUM&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;ETH remains ETH. You don't need to do anything from your side owing to this change. All you need to know is that Ethereum now has a new engine based on PoS which is eco-friendly, slightly faster, scalable, and more secure.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This article is more about the technical details of the Ethereum blockchain. Anything related to cryptocurrency is not in the scope of this discussion.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.bitmex.com/bitcoin-vs-ethereum-blockchain-size/"&gt;Bitcoin vs Ethereum Blockchain Size&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ethereum.org/en/upgrades/merge/"&gt;Ethereum Merge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ethereum.org/en/upgrades/beacon-chain/"&gt;Beacon Chain&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.ethereum.org/2022/01/24/the-great-eth2-renaming"&gt;Eth2 Renaming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/"&gt;Proof-of-Stake&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ethereum.org/en/developers/docs/networks/"&gt;Ethereum Networks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ethereum</category>
      <category>merge</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Node Package Manager (NPM)</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Wed, 20 Apr 2022 15:02:43 +0000</pubDate>
      <link>https://forem.com/rksainath/node-package-manager-npm-4ann</link>
      <guid>https://forem.com/rksainath/node-package-manager-npm-4ann</guid>
      <description>&lt;h3&gt;
  
  
  Need for NPM
&lt;/h3&gt;

&lt;p&gt;Node.js has got built-in modules for accessing the file system, networking, and other I/O operations. The problem is it offers only essential packages as core modules. We often want to use some external packages to re-use code and avoid complexity. Node has a way to cater to these packages through the node package manager (&lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt;). NPM offers a fleet of packages that are highly used in production-grade apps. &lt;a href="https://www.npmjs.com/package/express"&gt;Express&lt;/a&gt; is one such example that has seen a wider adoption. We will learn more about express.js in an upcoming post, stay tuned to this Node.js series. Also, there are many notable packages like &lt;em&gt;react, react-dom, underscore, vue, axios, body-parser&lt;/em&gt;, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initiate NPM
&lt;/h3&gt;

&lt;p&gt;To start with npm one can straightaway begin to use it. It is by default installed during the node.js installation. However, if you want to check the version, you can do it in the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm --version

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

&lt;/div&gt;



&lt;p&gt;The first thing one has to do to import npm packages is to create a folder and initiate npm in it. To initiate npm, navigate to your project folder in the terminal (in the case of windows, use the command prompt) and run &lt;code&gt;npm init&lt;/code&gt;. You will get a list of questionnaires to which you can input your preferences. In the interactive terminal, if nothing is filled it will populate a default value for certain fields like package name, version, and leaves it blank for description, author, etc. Press enter to move on to the next item. In the end, a JSON is created with a list of key-value items that you gave as input.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SFCKdl_B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650451881085/GhjWxTCk8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SFCKdl_B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650451881085/GhjWxTCk8.png" alt="npm init" width="609" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A short way to quickly do the initiation is by running &lt;code&gt;npm init --yes&lt;/code&gt;. The &lt;code&gt;yes&lt;/code&gt; flag will populate default values and skips the interactive questions to the user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4hKmrR-2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650451945822/BbTz9wrzM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4hKmrR-2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650451945822/BbTz9wrzM.png" alt="npm init yes" width="479" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing a package
&lt;/h3&gt;

&lt;p&gt;The &lt;em&gt;package.json&lt;/em&gt; created by npm can be found inside the project folder. This file is a snapshot of the list of dependencies for the project. &lt;strong&gt;It is necessary and be cautious to not delete this file&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9Zl9x7m7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650452093828/guBsWg4La.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9Zl9x7m7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650452093828/guBsWg4La.png" alt="package.json" width="773" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The packages can be installed using npm commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install &amp;lt;package-name&amp;gt; --save

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

&lt;/div&gt;



&lt;p&gt;This command will add the package to your local project and the scope remains local i.e. you can't access the package outside of this folder.&lt;/p&gt;

&lt;p&gt;Let's go ahead and install a package for our project. I am going to install &lt;a href="https://www.npmjs.com/package/chalk"&gt;chalk&lt;/a&gt; which helps in rendering colorful output in the console and this will be useful when you design CLI-based applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install chalk --save

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

&lt;/div&gt;



&lt;p&gt;If everything goes well, the package gets added to the project. If you are getting errors while downloading, check your installation and head to the official project page to see if there are any issues reported.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FFrUCK4p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650458346078/CVs_YAgW3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FFrUCK4p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650458346078/CVs_YAgW3.png" alt="chalk installation" width="502" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find the package name and version in the package.json under dependencies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ymC5d7E---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650459915112/bl0LQfSCZ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ymC5d7E---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650459915112/bl0LQfSCZ.png" alt="package-dependencies" width="729" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  node_modules
&lt;/h3&gt;

&lt;p&gt;You can see an additional folder named node_modules got added to our project. It consists of files related to the dependencies that were installed. The size of node_modules is huge and it is downloaded to your machine. You can often find the node_modules folder ignored while pushing your code to the repository. It can also be deleted and a fresh installation of packages can be triggered. Once you have package.json in place, it is no longer necessary to mention the package name to reinstall. All the details of the package and its version are available in the package.json and the installation will pick it up from there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;p&gt;There is an option to segregate dependencies based on usage. Not all packages are necessary to be installed, some are meant for development purposes like the &lt;a href="https://www.npmjs.com/package/nodemon"&gt;nodemon&lt;/a&gt; package. Nodemon keeps a watch on your file changes and automatically restarts the node application. This need not be added to your production environment as a dependency as you won't be making any file changes in production. To save a dependency for development purposes, add a flag &lt;code&gt;--save-dev&lt;/code&gt; instead of &lt;code&gt;--save&lt;/code&gt;. In contrast to local, there is an option to download a package globally to be used by any project by appending the flag &lt;code&gt;-g&lt;/code&gt; or &lt;code&gt;--global&lt;/code&gt; to the installation package. It is available globally but limited to your machine where it is installed. It is not necessary to install a global package in a project as is it a one-time installation and it will be available to use when imported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install nodemon --save-dev
npm install nodemon -g

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using the installed package
&lt;/h3&gt;

&lt;p&gt;To use a package it should be imported. Different module formats have their unique way of importing. The most known formats are CommonJS(CJS) and ES2015 Modules(ESM). There are also other formats like Asynchronous Module Definition (AMD) and Universal Module Definition (UMD) which you can explore in detail. Packages that use the ESM format insist to import the format using &lt;code&gt;import&lt;/code&gt; and the CJS format needs to use &lt;code&gt;require&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#ESM 
import chalk from 'chalk'

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

&lt;/div&gt;



&lt;p&gt;To use chalk as CJS format, the &lt;a href="https://github.com/chalk/chalk"&gt;documentation&lt;/a&gt; specifies to downgrade the version as the latest version supports EJS format.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Chalk 5 is ESM. If you want to use Chalk with TypeScript or a build tool, you will probably want to use Chalk 4 for now.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#CJS
const chalk = require('chalk')

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

&lt;/div&gt;



&lt;p&gt;In our example, I have used the ESM format to import the chalk module. An additional entry of &lt;code&gt;type: "module"&lt;/code&gt; has to be provided in package.json for using ESM format. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k7p_IY_k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650464615948/eInCWCIC-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k7p_IY_k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650464615948/eInCWCIC-.png" alt="Screenshot 2022-04-20 at 19.52.14.png" width="563" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create an &lt;em&gt;index.js&lt;/em&gt; file and import the 'chalk' module. Chalk can now be used to log your output colorfully. Check more about chalk and try it yourself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X9VZ3GcN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650464631580/QQBAaEO0K.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X9VZ3GcN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650464631580/QQBAaEO0K.png" alt="Screenshot 2022-04-20 at 19.51.41.png" width="774" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this post helped you in understanding the usage of npm. This post only caters to the essentials, you can go deep and learn about the detailed usage of npm on their official page.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/"&gt;NPM Official&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/"&gt;NPM Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code-trotter.com/web/understand-the-different-javascript-modules-formats/"&gt;Javascript Module Formats&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/chalk/chalk"&gt;Chalk GitHub Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>npm</category>
      <category>node</category>
    </item>
    <item>
      <title>Introduction to Node.js</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Tue, 19 Apr 2022 03:57:02 +0000</pubDate>
      <link>https://forem.com/rksainath/introduction-to-nodejs-22p</link>
      <guid>https://forem.com/rksainath/introduction-to-nodejs-22p</guid>
      <description>&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;Welcome to the Node.js learning series. This series will walk you through from basics to advanced concepts of Node.js. I will try my best to explain the concepts more simpler. Without further ado let us jump into the sea of Node.js.&lt;/p&gt;

&lt;p&gt;Node.js is a very popular backend javascript runtime environment. Back in time, there were only a few languages like Java, Python, Php, etc. that helped build a backend to do all complex tasks. The developers needed to learn multiple tech stacks to build the front and backend of an application. This became hard and the developer groups were segregated into frontend engineers and backend engineers. The rise of Node.js was the first big step toward full-stack web development. It gave rise to a plethora of full-stack developers who can code both frontend and backend in one single language i.e &lt;em&gt;Javascript&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Javascript
&lt;/h4&gt;

&lt;p&gt;Javascript is the blood of Node.js. Javascript knowledge must be required even before continuing with Node.js. If you are a newcomer, bookmark this post for future reference and continue learning javascript. Some important concepts that are needed to better understand Node.js.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Objects&lt;/li&gt;
&lt;li&gt;Functions&lt;/li&gt;
&lt;li&gt;Classes&lt;/li&gt;
&lt;li&gt;Asynchronous&lt;/li&gt;
&lt;li&gt;Callbacks&lt;/li&gt;
&lt;li&gt;Arrow Functions&lt;/li&gt;
&lt;li&gt;Promises&lt;/li&gt;
&lt;li&gt;Async/Await&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hop on to the next topic if you are good with the topics listed above.&lt;/p&gt;

&lt;h4&gt;
  
  
  Node.js Basics
&lt;/h4&gt;

&lt;p&gt;Node.js can be installed on any platform (Windows, macOS, Linux). The steps to install and different download formats are available on the official page of &lt;a href="https://nodejs.org/en/download/"&gt;node.js&lt;/a&gt;. Make sure you have installed the setup correctly and always install the latest stable version of the node.js. NPM gets installed along with node.js installation. We can discuss NPM in upcoming topics. Check your node and npm versions after the installations are complete.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node --version
npm --version

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

&lt;/div&gt;



&lt;p&gt;You are now ready to hack and let's start with the scripting. It is very boring to learn the concepts if you don't connect the dots. Hence we will learn the concepts by building a simple app. Our mission is to build a library application.&lt;/p&gt;

&lt;p&gt;Open a suitable &lt;a href="https://www.google.com/search?q=integrated+development+environment"&gt;IDE&lt;/a&gt; of your choice. I prefer &lt;a href="https://code.visualstudio.com/"&gt;Visual Studio Code&lt;/a&gt; and I have been using it as my default editor for web development. Open a folder and create a javascript file and name it of your choice &lt;code&gt;filename.js&lt;/code&gt;. It can be of any name but in general, the standard practice for naming the main file would be app.js, server.js, and index.js. I am naming it server.js. Open your file and start with writing the first line.&lt;/p&gt;

&lt;p&gt;Any programming language will have the first line with import statements. Similar is the case with node.js. It is not necessary that you should always have imports but commonly to use the inbuilt standard packages you may need to require the libraries to use them. For our online library, we need a server to get requests from clients, solve their queries and respond. Feel free to know more about client-server architecture and how the web works. In some frameworks like Php one may need to spin a separate web server and attach it to the main program but in the case of node.js everything is offered in one plate.&lt;/p&gt;

&lt;h4&gt;
  
  
  Built-in Modules
&lt;/h4&gt;

&lt;p&gt;Node.js has got this built-in HTTP library that handles server creation. To import a module or package, use &lt;code&gt;require&lt;/code&gt; and pass the module/package name. Since we need the HTTP package, we will import with &lt;code&gt;require('http')&lt;/code&gt;. The imported package can then be assigned to a constant for local use. It can also be assigned to a variable but it is prudent that we are not going to alter the package and that's why it is assigned to a constant.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const http = require('http')

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

&lt;/div&gt;



&lt;p&gt;Built-in modules help us to interact with the operating system, file system, networking, I/O operation, and a bunch of other kinds of stuff. There are different built-in modules apart from HTTP. You can read more about it on the official &lt;a href="https://nodejs.org/api/modules.html"&gt;documentation&lt;/a&gt; page. Here is an example of writing content to a file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fs = require('fs')

fs.writeFileSync('file.txt', 'Hello, welcome to online library')

console.log('Completed writing to file')

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

&lt;/div&gt;



&lt;p&gt;The above snippet shows how to import the file system module. It has different methods out of which we use &lt;code&gt;writeFileSync&lt;/code&gt; to write content to a file and create it on run-time. The word sync in &lt;code&gt;writeFileSync&lt;/code&gt; has to be kept in mind as we move further we will get to know about synchronous and asynchronous operations in node.js.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create Server
&lt;/h4&gt;

&lt;p&gt;Let us now create a server in your local machine that can be accessed through localhost. We have already imported the HTTP module and now we will use one of its methods &lt;code&gt;createServer&lt;/code&gt; which accepts &lt;code&gt;requestListener&lt;/code&gt; as an input argument and returns a server. &lt;code&gt;requestListener&lt;/code&gt; is a function that accepts two arguments 'request' and 'response' denoted as 'req' and 'res'. The &lt;code&gt;requestListener&lt;/code&gt; function will be called whenever there is an HTTP request. The request can be received and served by making the server listen. The &lt;code&gt;listen&lt;/code&gt; method will facilitate this by getting the inputs like hostname, port, etc. The server can also respond with headers like HTTP status codes which denote if the request has succeeded or not. Also, one can return an HTML output as a response when a specific request is made in the URL. For example, whenever there is a request to the root &lt;a href="http://localhost:4000/"&gt;http://localhost:4000/&lt;/a&gt;, it can be pointed to a landing page/ home page with a welcome message. Once the response has been served to the client, it has to be ended, else it will keep on staying in the event loop waiting for other requests. In short, you will see the page keep on loading.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#server.js

const http = require('http')

const server = http.createServer((req, res) =&amp;gt; {
  res.statusCode = 200
  res.write('&amp;lt;h1&amp;gt;Welcome to Online Library&amp;lt;/h1&amp;gt;')
  res.end()
})

server.listen(4000)

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Routing Requests
&lt;/h4&gt;

&lt;p&gt;Requests can be served depending on the type of request received. Imagine a post office segregating the mail based on addresses. Likewise, a request can be routed based on the URL. Let us redo our server.js file to make it less clumsy and add a new file routes.js to define the routes. It is simple to have a single route defined for a test application but in reality, even a simple application would serve multiple requests. We will separate the &lt;code&gt;requestListener&lt;/code&gt; from server.js and define all the routes in routes.js file.&lt;/p&gt;

&lt;p&gt;In the routes.js, we are going to define two routes for our online library. The root path &lt;code&gt;/&lt;/code&gt; will act as a landing page and the &lt;code&gt;/books&lt;/code&gt; will show the list of books in our library. We will abstract the &lt;code&gt;requestListener&lt;/code&gt; function in server.js and define it in routes.js. The &lt;code&gt;requestListener&lt;/code&gt; function will be exported from routes.js and this module can be imported like any other module in server.js. We will assign the function to &lt;code&gt;reqHandler&lt;/code&gt; and export the module using &lt;code&gt;module.exports&lt;/code&gt;. Inside the requestListener function let us define the routes to be handled. We will create a simple &lt;code&gt;if&lt;/code&gt; condition to switch between routes based on the request URL. The request returns a pile of data as a JSON object. You can have a look by printing the request in the console &lt;code&gt;console.log(req)&lt;/code&gt;. We are more interested in categorizing based on the URL. The request can be parsed by getting the value of URL. &lt;code&gt;req.url&lt;/code&gt; will return the URL (&lt;a href="http://localhost:4000/"&gt;http://localhost:4000/&lt;/a&gt;) that was requested by the client. We will grab the URL and compare it with our logic to route it. In the case of the root path, it is straightforward where we just return a response with an HTTP status code of &lt;code&gt;200&lt;/code&gt; and a welcome message in the HTML body. If the URL has &lt;code&gt;/books&lt;/code&gt; then we need to populate it with a list of books which is done using the &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; tag in our HTML response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#routes.js

const reqHandler = (req, res) =&amp;gt; {
  const url = req.url
  const method = req.method
  if (url === '/') {
    res.statusCode = 200
    res.write('&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Library&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Welcome to Online Library&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;')
    return res.end()
  } else if (url === '/books') {
    res.statusCode = 200
    res.write(
      "&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;List of Books&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;'So Good They Can't Ignore You'&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;'Deep Work'&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;'Digital Minimalism'&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;'Atomic Habits'&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;'Thinking, fast and slow'&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"
    )
    return res.end()
  }
}

module.exports = reqHandler

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

&lt;/div&gt;



&lt;p&gt;We will now import the &lt;code&gt;requestListener&lt;/code&gt; function in the server.js file by importing the routes.js. The imported routes module is now passed as an input to the &lt;code&gt;createServer&lt;/code&gt; function which is nothing but the &lt;code&gt;requestListener&lt;/code&gt; function that we created on the routes.js file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#server.js

const http = require('http')
const routes = require('./routes')
const server = http.createServer(routes)
server.listen(4000)

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

&lt;/div&gt;



&lt;p&gt;Once everything is connected, you will see the following output on your browser.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="http://localhost:4000/"&gt;http://localhost:4000/&lt;/a&gt;&lt;/em&gt; &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yLcNOLJF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650338360583/eIoE4IiWV.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yLcNOLJF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650338360583/eIoE4IiWV.png" alt="landing page" width="880" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="http://localhost:4000/books"&gt;http://localhost:4000/books&lt;/a&gt;&lt;/em&gt; &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TuhPJWUF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650338385995/jrJRq2Ki-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TuhPJWUF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650338385995/jrJRq2Ki-.png" alt="books page" width="880" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this post will help you quickly set up a node server. There are other concepts like blocking/non-blocking, asynchronous, callbacks, etc which are more important when you write I/O intensive operations. Node.js primarily does asynchronous execution to avoid waiting for a single request to resolve. It will serve whenever a new request is received and resumes back to the previous request using a callback to resolve whenever it is ready. Get a good hold of these concepts by reading through the official documentation of node.js. You can find below some useful links to delve more into these topics.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/"&gt;Anatomy of an HTTP transaction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/"&gt;Event Loops&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/"&gt;Blocking vs Non-Blocking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/knowledge/getting-started/control-flow/what-are-callbacks/"&gt;Callbacks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
    </item>
    <item>
      <title>Cognitive and Learning Disabilities Accessibility Task Force (aka) COGA</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Sun, 23 May 2021 00:00:00 +0000</pubDate>
      <link>https://forem.com/rksainath/cognitive-and-learning-disabilities-accessibility-task-force-aka-coga-52c9</link>
      <guid>https://forem.com/rksainath/cognitive-and-learning-disabilities-accessibility-task-force-aka-coga-52c9</guid>
      <description>&lt;p&gt;Accessibility is a well-known practice and most product developers and organizations give importance to it to ensure their content/application caters to everyones needs. I am not going to dwell on accessibility as there are lots of posts concerning that. Here is a short explanation of accessibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Accessibility&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Accessibility is an approach to enable differently-abled users to access the application or user interface by introducing supporting features to assist them. Provisions like reading out the content, enlarged-view, talkback, etc help the challenged users access the content without hassle. To incorporate this as a guideline W3C (Worldwide Web Consortium) introduced a separate guideline called WCAG (Web Content Accessibility Guideline) to enhance the user experience. Also, they keep publishing new changes year on year to improve the features. One such draft that was recently published on Making Content Usable for People with Cognitive and Learning Disabilities, shortly named COGA and it is going to be the primary focus of this post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A_6nmlJV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204803242/iDUWGPgBK.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A_6nmlJV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204803242/iDUWGPgBK.png" alt="An image showing Sundar Pichai talking" width="880" height="441"&gt;&lt;/a&gt;&lt;em&gt;Source: MKBHD&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Even if you think of it as a feature to help the disabled community, it has wide applicability beyond that.&lt;/p&gt;

&lt;p&gt;Sundar Pichai during an interview with MKBHD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;During Google I/O 2021, Sundar Pichai was &lt;a href="https://youtu.be/n2RNcPRtAiY"&gt;interviewed&lt;/a&gt; by Marques Brownlee in which Sundar mentioned the importance of accessibility. Accessibility is not a feature that is designed only to help the differently-abled but to everyone during their temporary disability at any part of their life. It might be an accident that could have made their arm to be not usable for a certain period. It could be a senior citizen whose vision and hearing would decrease due to their age. It could be a feeding mother who always needs to use her mobile in one hand. So, accessibility is better to be said as a general guideline to enable users to access content using enhanced features to support them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h_Pu9OYg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204804956/XXaVq3fYz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h_Pu9OYg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204804956/XXaVq3fYz.png" alt="An image showing the illustration of how many people are disabled in the world." width="880" height="541"&gt;&lt;/a&gt;&lt;em&gt;Source: Google Developers&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cognitive and Learning Disabilities Accessibility Task Force
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;COGA was initiated by WCAG to attend to the needs of the users who find difficulty in understanding the content on the web.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://twitter.com/w3c/status/1390295033987751937?s=20"&gt;https://twitter.com/w3c/status/1390295033987751937?s=20&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.w3.org/TR/WCAG22/"&gt;draft&lt;/a&gt; emphasizes simplifying the content to the challenged users by providing them assistance and features to understand better. Learning and cognitive disability could occur to anyone owing to age or other mishaps. Let us understand better how we could improve this.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Numbers&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--78Uh5hma--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204806571/pwFB5R1g9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--78Uh5hma--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204806571/pwFB5R1g9.png" alt="Weather condition" width="550" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://weather.com/"&gt;https://weather.com/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Numbers play an important role in statistical websites or financial or data-intensive applications. Historical facts, weather reports, stock market prices, and the list can go on. A normal user without any domain-specific knowledge would be interested in knowing the outcome of these data rather than the number itself. Say if a weather report says 40 degrees or wet clouds then it is prudent to convey the user to wear a hat or take an umbrella along with the numerical data. A stock price thats soaring high or falling low can be indicated by arrow symbols and emojis to quickly give a glimpse of the situation. Any data that is represented raw will not add value to the story being conveyed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Date &amp;amp; Time
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y_ivRYTV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204807911/1NE_MIole.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y_ivRYTV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204807911/1NE_MIole.png" alt="Picture of date format picker" width="325" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://support.microsoft.com/"&gt;https://support.microsoft.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Across the globe, there are different time zones and different formats of date conventions that are being followed. Achieving unique formats is difficult as everyone would have got accustomed to specific formats. I am good with the format DD/MM/YYYY or DD/MM/YY, other formats might confuse me where I would pause to understand what month it is. This is because our minds are trained by the continuous usage of it. We cant label this as a disability rather a preferred way would be apt to tell. If an application is built for a global audience, all formats of date and time must be presented to them. Another example would be related to time. If there is an event that is happening in a specific time zone and the users participating would be interested in knowing the local time of the event rather than the actual time zone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visuals
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5RHfMpXw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204809391/INN2Ghr8e.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5RHfMpXw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204809391/INN2Ghr8e.jpeg" alt="" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@robowunderkind?utm_source=medium&amp;amp;utm_medium=referral"&gt;Robo Wunderkind&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Visual learners are the ones who need assistive diagrams, illustrations, etc to understand the context. Reading a story or novel will give you a mental image where you feel like you are in the story whereas advanced concepts, theorems, axioms, or scientific principles on the web are likely to be completely text and numbers. To assist visual learners it might be helpful if the explanations are coupled with illustrations and graphics. The combinations of text and illustration or an image could give a better grasp rather than a misconception.&lt;/p&gt;

&lt;h3&gt;
  
  
  Text
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oYUaMAPX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204811437/4linMA1i8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oYUaMAPX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204811437/4linMA1i8.jpeg" alt="Wikipedia web page" width="880" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@lukechesser?utm_source=medium&amp;amp;utm_medium=referral"&gt;Luke Chesser&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We often encounter websites having long texts, the best example is Wikipedia. Those are informational websites that tend to be full of texts as it is necessary to read an entire page to get a complete understanding (similar to my current post 😁). To get the context, one has to run through the entire content which is time-consuming whereas if we could provide a video summary, a gist, or an infographic would help them understand the concept and read through to get the complete essence of the content. Also, the font sizes should be compatible to let the users change as and when required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Audio and Video
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5hm7h62x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204813098/qvyu_8RDf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5hm7h62x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204813098/qvyu_8RDf.jpeg" alt="A computer with audio equipments" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@kellysikkema?utm_source=medium&amp;amp;utm_medium=referral"&gt;Kelly Sikkema&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are smart devices that require inputs from users to enact based on voice commands. It can also be a recording device that indicates to the user that voice/sound is being recorded. Similarly Google Assistant, Alexa, and others respond to users that they are listening using a light or sound indication that it is listening else the user would never know if the input is actually received.&lt;/p&gt;

&lt;h3&gt;
  
  
  Forms
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uyA5yuWO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204815153/eAQxaRy_s.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uyA5yuWO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204815153/eAQxaRy_s.jpeg" alt="Application form" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@kellysikkema?utm_source=medium&amp;amp;utm_medium=referral"&gt;Kelly Sikkema&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Forms are a set of questions that need to be answered. Filling the form can be a text box or a multiple choice field. Questions like Do you agree with this? will have options like I Agree, I Strongly Agree, and Do Not Agree. The options I Agree and I Strongly Agree are relatively the same and this creates unnecessary confusion and it is difficult to measure the agreeability. Hence binary options will always be straightforward and can give a better outcome.&lt;/p&gt;

&lt;h3&gt;
  
  
  Product Study
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mHC0WQkw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204816803/zrKFRuiUn.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mHC0WQkw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204816803/zrKFRuiUn.jpeg" alt="Group of people sitting in a meeting" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@campaign_creators?utm_source=medium&amp;amp;utm_medium=referral"&gt;Campaign Creators&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A product has to be well researched before shipping to the market. Never design multiple copies of the same product to cater to accessibility needs. It shows that you are discriminating against people with accessibility needs and as mentioned at the beginning of the topic, accessibility is not only for people with special needs but for everyone at a different point in time. Give out the application or product for feedback and observe the reaction from peoples faces. If they are confused and blinking, it means they dont understand your product. If they feel happy and relaxed, you are on the way to AAA accessibility score.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Tools
&lt;/h3&gt;

&lt;p&gt;Considering the need for accessibility, technology companies have come up with tool kits and software to support accessibility. Commonly, people often use mobile devices as their primary tool so the major players have defined their own accessibility tool kits to help their users.&lt;/p&gt;

&lt;p&gt;Googles Android offers a range of accessibility services viz. screen reader, display controls, interaction controls, braille display, audio, and on-screen text. Check out more on &lt;a href="https://support.google.com/accessibility/android#topic=6007234"&gt;Android accessibility&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Apples iOS has classified accessibility into vision, physical, and motor. Check out more on &lt;a href="https://support.apple.com/en-gb/HT210433"&gt;iOS accessibility&lt;/a&gt; features.&lt;/p&gt;

&lt;p&gt;Players involved in accessibility support: &lt;a href="https://www.microsoft.com/en-in/accessibility?rtc=1"&gt;Microsoft&lt;/a&gt;, &lt;a href="https://support.apple.com/en-in/accessibility"&gt;Apple&lt;/a&gt;, &lt;a href="https://www.google.com/accessibility/"&gt;Google&lt;/a&gt;, &lt;a href="https://en-gb.facebook.com/accessibility"&gt;Facebook&lt;/a&gt;, &lt;a href="https://twitter.com/twittera11y"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;References&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://mn.gov/mnit/media/blog/?id=38-373446"&gt;Minnesota IT Services Blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.w3.org/WAI/GL/task-forces/coga/work-statement"&gt;COGA Guidelines&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.w3.org/TR/WCAG22/"&gt;WCAG 2.2&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>coga</category>
    </item>
    <item>
      <title>SQL: Basics to Advanced in a Nutshell</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Wed, 10 Mar 2021 10:51:49 +0000</pubDate>
      <link>https://forem.com/rksainath/sql-basics-to-advanced-in-a-nutshell-b2g</link>
      <guid>https://forem.com/rksainath/sql-basics-to-advanced-in-a-nutshell-b2g</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover Photo by &lt;a href="https://www.pexels.com/@divinetechygirl?utm_content=attributionCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=pexels" rel="noopener noreferrer"&gt;Christina Morillo&lt;/a&gt; from &lt;a href="https://www.pexels.com/photo/man-standing-infront-of-white-board-1181345/?utm_content=attributionCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=pexels" rel="noopener noreferrer"&gt;Pexels&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Databases are the containers/repository of data. They hold the data in the form of a spreadsheet(not the same but for the sake of imagination). There are many databases viz. Relational and Non-Relational. Let us not dwell on the latter part but stick with the relational databases. Watch this video to know more about databases.&lt;/p&gt;

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

&lt;p&gt;This post will focus primarily on writing SQL queries. SQL queries are common across all the databases but there are some flavors and they may vary according to different databases. There are various vendors like IBM, MySQL, PostgreSQL, Oracle, etc. Every vendor has its own style of SQL to communicate with its database. The one I would suggest is &lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; which is open source and has got wider adoption.&lt;/p&gt;

&lt;p&gt;The primary way to communicate with a relational database is through SQL. Structured Query Language (SQL) is a language to communicate with the database. Without further ado, let us jump into learning SQL.&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;Image Source: &lt;a href="https://thedatalabs.org/spreadsheet-structure/" rel="noopener noreferrer"&gt;The Data Labs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A table looks like the above spreadsheet with rows and columns. Columns are the headers for the category of the values that we input. A column that is defined as a name will have only names in it and a column defined as a currency would certainly have numbers in the entire column. So, a column defines what kind of values it should comprise. Rows are the list of entries made in different columns. Rows define the number of entries in a spreadsheet.&lt;/p&gt;

&lt;p&gt;Now, to get all the columns from the customer table, we use the keyword &lt;code&gt;SELECT&lt;/code&gt; and specify the column names that we are interested in. We can use the &lt;code&gt;*&lt;/code&gt; symbol to fetch all the columns from the table. To connect to a table, the keyword &lt;code&gt;FROM&lt;/code&gt; is used which comes after the &lt;code&gt;SELECT&lt;/code&gt; keyword.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get specific columns from the customer table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In spreadsheets, we would have used filters similar to that in SQL there are filters to query. For instance, if you want to look only for emails that have the first name as 'Sai', the keyword that should be used is &lt;code&gt;WHERE&lt;/code&gt;. &lt;code&gt;WHERE&lt;/code&gt; should be used after the &lt;code&gt;FROM&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Sai'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get all the emails of the customer whose first name is 'Sai' and the last name is 'Kumar', we use a keyword called &lt;code&gt;AND&lt;/code&gt; which is a logical operator similar to &lt;code&gt;OR&lt;/code&gt;, and &lt;code&gt;NOT&lt;/code&gt;. You can learn more about &lt;a href="https://www.w3resource.com/sql/boolean-operator/sql-boolean-operators.php" rel="noopener noreferrer"&gt;logical operators&lt;/a&gt; in SQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Sai'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Kumar'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get all the emails of the customer whose first name is 'Sai' or the last name is 'Kumar'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Sai'&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Kumar'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To arrange the data in ascending or descending order use the &lt;code&gt;ORDER BY&lt;/code&gt; keyword followed by the column name based on which the entire table would be ordered. To arrange is ascending use &lt;code&gt;ASC&lt;/code&gt; and for descending &lt;code&gt;DESC&lt;/code&gt;. By default if you don't specify the order, it will sort the column in ascending order. &lt;code&gt;ORDER BY&lt;/code&gt; always comes at the tail end of the query.&lt;/p&gt;

&lt;p&gt;To get the list of customer ids and arrange them in ascending order of their transaction date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;transaction_date&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the list of customer ids and arrange them in descending order of their transaction date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;transaction_date&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also limit the number of records displayed by using &lt;code&gt;LIMIT&lt;/code&gt; with a positive integer number to specify the limit.&lt;/p&gt;

&lt;p&gt;To get the list of the first 10 customer ids.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;transaction_date&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;COUNT&lt;/code&gt; is a type of function that is used in columns and it should come after the &lt;code&gt;SELECT&lt;/code&gt;. &lt;code&gt;COUNT&lt;/code&gt; returns the number of data in the specified column. In general, passing &lt;code&gt;*&lt;/code&gt; as an argument to the &lt;code&gt;COUNT&lt;/code&gt; will also return the same result as the column name.&lt;/p&gt;

&lt;p&gt;To get the count of some customers whose age is not more than 50.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The use of regular expressions is ubiquitous in all programming languages similarly we use regex in SQL to match the strings. &lt;code&gt;LIKE&lt;/code&gt; is used in conjunction with &lt;code&gt;WHERE&lt;/code&gt; and followed by the regex. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;%String&lt;/code&gt; - grabs all the words that end with &lt;code&gt;String&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;String%&lt;/code&gt; - grabs all the words that start with &lt;code&gt;String&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;%String%&lt;/code&gt; - grabs all the words that comprise
the &lt;code&gt;String&lt;/code&gt; in between them
Note: &lt;code&gt;LIKE&lt;/code&gt; is case sensitive and looks only for the string that is mentioned. &lt;code&gt;ILIKE&lt;/code&gt; is an alternative that is case insensitive and can match across various cases of the string.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To get all the names of the customer whose first letter in their first name starts with 'P'&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'P%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get all the customers whose last name has 'siva' in between and should be case insensitive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="k"&gt;ILIKE&lt;/span&gt; &lt;span class="s1"&gt;'%siva%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At times the entries in the table might have duplicate data. To filter out unique data, &lt;code&gt;DISTINCT&lt;/code&gt; is used. &lt;code&gt;DISTINCT&lt;/code&gt; applies only to the column and comes next to &lt;code&gt;SELECT&lt;/code&gt; and even as an argument to the &lt;code&gt;COUNT&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;To get the count of distinct areas where the customers are from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;area&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get distinct areas where the customers are from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;area&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;IN&lt;/code&gt; is used to specify the list of items against which a column is compared. For example, we can check if a column consists of (Orange, Mango, Banana) and the function filters and display only the entries with orange, mango, and banana.&lt;/p&gt;

&lt;p&gt;To get the count of customers who are located in the area with Pincode '82' between the age group 60 to 70.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;pincode&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="k"&gt;BETWEEN&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AGGREGATION
&lt;/h3&gt;

&lt;p&gt;Aggregation means a cluster of things that are brought together. Likewise aggregation in SQL clusters the data into a homogeneous category and groups it. For example,&lt;/p&gt;

&lt;p&gt;To get the total number of transactions made by all customers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transaction_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here &lt;code&gt;COUNT&lt;/code&gt; is the aggregation function that has been performed on the transaction_date column concerning the customer_id. So a group is formed for every customer_id where you will get a matching count of the number of transactions. A normal &lt;code&gt;COUNT&lt;/code&gt; would have resulted in the total number of transactions whereas in aggregation with customer_id by using &lt;code&gt;GROUP BY&lt;/code&gt;, it produces a table with individual customer ids and their corresponding count of transactions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GROUP BY&lt;/code&gt; should always have the column names that are mentioned in the &lt;code&gt;SELECT&lt;/code&gt; criteria except for the aggregation function.&lt;/p&gt;

&lt;p&gt;To get an average amount that a customer has spent on purchases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get a rounded value of the average calculated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To arrange the SUM(amount) in descending order and display only 10 rows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is not possible to use the &lt;code&gt;WHERE&lt;/code&gt; condition on the aggregate function and that is where we use &lt;code&gt;HAVING&lt;/code&gt; after the &lt;code&gt;GROUP BY&lt;/code&gt; and specify the condition.&lt;/p&gt;

&lt;p&gt;To display the customers who have spent more than 100 INR.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To display the customers who were attended by the staff with id '2' and their total spending is more than 1000 INR.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;staff_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;staff_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;staff_id&lt;/span&gt; &lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JOINS
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;JOINS&lt;/code&gt; play an important role while analyzing data by combining multiple tables. There are four types of &lt;code&gt;JOINS&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;INNER JOIN&lt;/li&gt;
&lt;li&gt;LEFT OUTER JOIN&lt;/li&gt;
&lt;li&gt;RIGHT OUTER JOIN&lt;/li&gt;
&lt;li&gt;FULL OUTER JOIN&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;INNER JOIN&lt;/code&gt; - Compares between two tables on the specified columns and returns the data that matches in both the columns.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LEFT OUTER JOIN&lt;/code&gt; - Compares between two tables on the specified columns and returns the data that matches in the left table. If no value is present in the right table matching the left, then it returns the data as &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RIGHT OUTER JOIN&lt;/code&gt; - Compares between two tables on the specified columns and returns the data that matches in the right table. If no value is present in the left table matching the right, then it returns the data as &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;FULL OUTER JOIN&lt;/code&gt; - Compares between two tables on the specified columns and returns the data that matches in both the columns along with mismatches with a value as &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can read more about JOINS &lt;a href="https://www.diffen.com/difference/Inner_Join_vs_Outer_Join" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;INNER JOIN&lt;/code&gt; to merge two tables according to matching values of customer_id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;payment_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;FULL OUTER JOIN&lt;/code&gt; to merge two tables according to matching values of customer_id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;payment_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;FULL&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;LEFT OUTER JOIN&lt;/code&gt; to merge two tables according to matching values of customer_id based on the left table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;payment_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt; &lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;RIGHT OUTER JOIN&lt;/code&gt; to merge two tables according to matching values of customer_id based on the right table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;RIGHT&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use nested joins to query from multiple tables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;billing&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;billing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Sai'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Kumar'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Other SQL Commands
&lt;/h2&gt;

&lt;p&gt;To display the timezone of your current location.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;TIMEZONE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get today's timestamp.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the current time of the day.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;TIMEOFDAY&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To extract month, day, year from the timestamp use the function &lt;code&gt;EXTRACT&lt;/code&gt; which will return a numeric month, date, or year.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;EXTRACT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;MONTH&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;transaction_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To convert a timestamp into a specific string format like 'DD/MM/YYYY', the TO_CHAR function is used where you specify the timestamp column name as the first argument and followed by the format to be returned.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TO_CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'DD/MM/YYYY'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A sub query returns either a single data or a list of data which can be asserted with its parent query.&lt;br&gt;
-- SUB QUERY&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;Full_Name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;address_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;address_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;district&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Chennai'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similar to conditionals in programming languages, SQL has a &lt;code&gt;CASE&lt;/code&gt; statement that runs a check against the selected column and performs specified operations on it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="n"&gt;citizen&lt;/span&gt;
    &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="s1"&gt;'INDIAN'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="n"&gt;rating&lt;/span&gt;
    &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="s1"&gt;'NRI'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;NRI&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That will be all and there are few more concepts like views, procedures etc. which is much more advanced and I will cover those is my future posts.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Extent Reports made easy using Cucumber Adapter</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Tue, 09 Jun 2020 15:30:38 +0000</pubDate>
      <link>https://forem.com/rksainath/extent-reports-made-easy-using-cucumber-adapter-2l13</link>
      <guid>https://forem.com/rksainath/extent-reports-made-easy-using-cucumber-adapter-2l13</guid>
      <description>&lt;p&gt;Report! Report! and yes we all need reports of whatever we do. This applies to test automation as well and we have a lot of options to do that. Cucumber gives out reporting feature which is readily available inside the cucumber package but it looks pretty old and not insightful. To make our lives easy we have a readymade solution for it and that's called &lt;a href="http://extentreports.com/"&gt;Extent Reports&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before getting into the details there are two ways to achieve this as mentioned below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Long Route&lt;/strong&gt; - Using the Extent Reports with customizable configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Short Route&lt;/strong&gt; - Using the Extent Reports Adapter corresponding to the Cucumber version&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Long Route
&lt;/h2&gt;

&lt;p&gt;If you are building a Maven-based project, add the following dependencies to your pom.xml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- https://mvnrepository.com/artifact/com.vimalselvam/cucumber-extentsreport --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;com.vimalselvam&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;cucumber-extentsreport&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;3.1.1&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;!-- https://mvnrepository.com/artifact/com.aventstack/extentreports --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;com.aventstack&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;extentreports&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;4.1.5&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Note: If you are using Java 7 and below you don't need to add the second dependency but for Java 8 and above, you should add both the dependencies.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The next step is to create a configuration XML file. In your folder structure go to src/test/ and create a new folder called 'resources' (src/test/resources). Inside 'resources', create a new file called extent-config.xml (or any other name that you prefer) and add the following code in it. This XML defines how to display your report in the HTML page.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;extentreports&amp;gt;
  &amp;lt;configuration&amp;gt;
    &amp;lt;!-- report theme --&amp;gt; &amp;lt;!-- standard, dark --&amp;gt;
    &amp;lt;theme&amp;gt;standard&amp;lt;/theme&amp;gt;

    &amp;lt;!-- document encoding --&amp;gt;  &amp;lt;!-- defaults to UTF-8 --&amp;gt;
    &amp;lt;encoding&amp;gt;UTF-8&amp;lt;/encoding&amp;gt;

    &amp;lt;!-- protocol for script and stylesheets --&amp;gt;   &amp;lt;!-- defaults to https --&amp;gt;
    &amp;lt;protocol&amp;gt;https&amp;lt;/protocol&amp;gt;

    &amp;lt;!-- title of the document --&amp;gt;
    &amp;lt;documentTitle&amp;gt;BDD Cucumber Framework Reports&amp;lt;/documentTitle&amp;gt;

    &amp;lt;!-- report name - displayed at top-nav --&amp;gt;
    &amp;lt;reportName&amp;gt;Android - Cucumber Report&amp;lt;/reportName&amp;gt;

    &amp;lt;!-- global date format override --&amp;gt;  &amp;lt;!-- defaults to yyyy-MM-dd --&amp;gt;
    &amp;lt;dateFormat&amp;gt;yyyy-MM-dd&amp;lt;/dateFormat&amp;gt;

    &amp;lt;!-- global time format override --&amp;gt;   &amp;lt;!-- defaults to HH:mm:ss --&amp;gt;
    &amp;lt;timeFormat&amp;gt;HH:mm:ss&amp;lt;/timeFormat&amp;gt;

    &amp;lt;!-- custom javascript --&amp;gt;
    &amp;lt;scripts&amp;gt;
      &amp;lt;![CDATA[
        $(document).ready(function() {
        });
      ]]&amp;gt;
    &amp;lt;/scripts&amp;gt;

    &amp;lt;!-- custom styles --&amp;gt;
    &amp;lt;styles&amp;gt;
      &amp;lt;![CDATA[
      ]]&amp;gt;
    &amp;lt;/styles&amp;gt;
  &amp;lt;/configuration&amp;gt;
&amp;lt;/extentreports&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now you have to configure the Runner class to map with Extent Reports.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(
        features= "src/test/resources",
        tags = {"@RegressionTest"},
        monochrome = true,
        glue= {"stepDef"},
        plugin = {"com.cucumber.listener.ExtentCucumberFormatter:target/html/ExtentReport.html"})

public class RunnerTest {

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

&lt;/div&gt;


&lt;p&gt;Having set the plugin, the next step is to create an 'AfterClass' method to define the reporting parameters and to showcase the test results in the dashboard.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(
        features= "src/test/resources",
        tags = {"@RegressionTest"},
        monochrome = true,
        glue= {"stepDef"},
        plugin = {"com.cucumber.listener.ExtentCucumberFormatter:target/html/ExtentReport.html"})

public class RunnerTest {
Reporter.loadXMLConfig(new File("src/test/resources/extent-config.xml"));
Reporter.setSystemInfo("AUT Name", "Make My Trip");
Reporter.setSystemInfo("Environment", "Production");
Reporter.setTestRunnerOutput("BDD Cucumber Framework Reports");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's it! you have set up the reporter and when you execute the cases you can find the results under target/html/ExtentReport.html.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Short Route
&lt;/h2&gt;

&lt;p&gt;The Aventstack has always made our lives easy and to achieve this they have been releasing adapters for Cucumber versions 1, 2, 3, 4, and now for 5. Mind that 5 is in the test phase as of now since Cucumber is also new to 5, it is better to stick with version 4 of Cucumber at this point. You gotta pick the relevant adapter version corresponding to your Cucumber. I am using Cucumber 4 and I will be using the corresponding adapter which is 'extentreports-cucumber4-adapter'. Also for some, you may need to add the exclusions of 'cucumber-java' and 'cucumber-core' just to avoid the adapter from pulling its dependencies of Cucumber.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;com.aventstack&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;extentreports-cucumber4-adapter&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.0.8&amp;lt;/version&amp;gt;
            &amp;lt;exclusions&amp;gt;
                &amp;lt;exclusion&amp;gt;
                    &amp;lt;groupId&amp;gt;io.cucumber&amp;lt;/groupId&amp;gt;
                    &amp;lt;artifactId&amp;gt;cucumber-java&amp;lt;/artifactId&amp;gt;
                &amp;lt;/exclusion&amp;gt;
                &amp;lt;exclusion&amp;gt;
                    &amp;lt;groupId&amp;gt;io.cucumber&amp;lt;/groupId&amp;gt;
                    &amp;lt;artifactId&amp;gt;cucumber-core&amp;lt;/artifactId&amp;gt;
                &amp;lt;/exclusion&amp;gt;
            &amp;lt;/exclusions&amp;gt;
        &amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As mentioned in the above setup (in The Long Route) you may need to create a resources folder in 'src/test/' and initiate a file called extent.properties. This property file is similar to the configuration file mentioned previously but this is alight weighted file and you need to write just 3 steps to spin your report.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 1 - Tells the reporter to start the reporting&lt;/li&gt;
&lt;li&gt;Step 2 - Leave the config field empty as it is pre-defined in the adapter&lt;/li&gt;
&lt;li&gt;Step 3 - Specify where the report should be placed
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;extent.reporter.html.start=true
extent.reporter.html.config=
extent.reporter.html.out=test-output/HtmlReport/ExtentHtml.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You're almost done. Just go to your Runner class and add the following plugin inside the CucumberOptions.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(
        features= "src/test/resources",
        tags = {"@RegressionTest"},
        monochrome = true,
        glue= {"stepDef"},
        plugin = {"com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"})

public class RunnerTest {

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

&lt;/div&gt;


&lt;p&gt;This is so simple and you don't need to remember a lot of steps to set up the report. I prefer the short route to be employed and of course, if you need the customization, go for the long route. I have also added an example in my GitHub repository.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rksainath"&gt;
        rksainath
      &lt;/a&gt; / &lt;a href="https://github.com/rksainath/MMT-CukeTest"&gt;
        MMT-CukeTest
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is a cucumber test framework with added reporting feature using Extent Report
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>cucumber</category>
      <category>java</category>
      <category>reports</category>
    </item>
    <item>
      <title>Auto-Heal tests with recheck-web</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Fri, 05 Jun 2020 11:15:15 +0000</pubDate>
      <link>https://forem.com/sainathr/auto-heal-tests-with-recheck-web-dj</link>
      <guid>https://forem.com/sainathr/auto-heal-tests-with-recheck-web-dj</guid>
      <description>&lt;p&gt;This post is going to talk about auto-healing and the first thing that comes to your mind is Artificial Intelligence (AI). I do agree with that and it has been a cliche these days to make everything intelligent. The problem with AI is that you need to pre-process data, build a feature, pick an algorithm, and start training the system which may eventually take some time to improvise and get the desired outcome. Long story short, we don't have enough time for that in some cases. I am not offensive to AI, I evangelize about it all the time but still, it can't be applied for everything as "one shoe doesn't fit for all".&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto-Healing
&lt;/h3&gt;

&lt;p&gt;Auto-Healing in terms of computer science refers to the computer program that can correct itself whenever it encounters a blocker or a new change that has been incorporated in the system. In a normal scenario, the script would fail to proceed due to a lack of knowledge. Auto-healing makes sure that the system keeps up and running and does not break during its course.&lt;/p&gt;

&lt;p&gt;The kind of auto-healing that we are going to see here is specific to UI test automation where most of the automation engineers would agree that most of their time has been spent on fixing the code due to constant changes in the front-end. This is prevalent now as we have element attributes in HTML that keep changing dynamically because of the recent front-end frameworks that are being used. To overcome this problem without further ado let me introduce a framework called  &lt;a href="https://retest.de/recheck-web-open-source/" rel="noopener noreferrer"&gt;recheck-web&lt;/a&gt; which is from a company called &lt;a href="https://retest.de/" rel="noopener noreferrer"&gt;retest&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  recheck-web
&lt;/h3&gt;

&lt;p&gt;recheck-web works based on 'Difference Testing' where a Golden Master is created during the first run and it is considered as the reference. The Golden Master is a combination of screenshot and XML file which will have all the attributes related to elements on a web page. The following is a brief introduction to recheck-web from the company's official &lt;a href="https://github.com/retest/recheck-web" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; page.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can explicitly or implicitly create Golden Masters (essentially a copy of the rendered website) and semantically compare against these. Irrelevant changes are easy to ignore and the Golden Masters are effortless to update. In case of critical changes that would otherwise break your tests, recheck-web can now peek into the Golden Master, find the element there, and (based on additional attributes) still identify the changed element on the current website.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F1871610%2F65941692-e9dfdd80-e42b-11e9-8d07-d3284ea57f12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F1871610%2F65941692-e9dfdd80-e42b-11e9-8d07-d3284ea57f12.png" alt="Source: retest/recheck-web"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above image, the overall concept has been simplified into a diagram. It is prudent that the UI is always subjected to changes, having that as a problem recheck-web does the following actions,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A usual selenium test will break if it finds a locator is changed in the UI and if we have not updated the test script and throws NoSuchElementException&lt;/li&gt;
&lt;li&gt;A selenium test wrapped with recheck-web will have a Golden Master where all the attributes of the elements are captured for the entire page (only if you pass a driver but if a web element is passed, it would only capture the attributes of that particular element)&lt;/li&gt;
&lt;li&gt;If a test script is run against the new UI whilst having the old locators in place, it would not break rather the test will execute as it would refer to the Golden Master and compares the present state of the locator with previous history a.k.a the Golden Master&lt;/li&gt;
&lt;li&gt;The test would successfully execute all the functional validations but eventually will finish it with a warning and in a result, it shows what is expected and what has changed&lt;/li&gt;
&lt;li&gt;This not only applies to the locator changes but also this validates the CSS and any Style changes as well which benefits the visual validation&lt;/li&gt;
&lt;li&gt;The last step would be the decision making step where the user can accept all the changes or ignore it to update the Golden Master&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It might seem to be complex to grasp but I will debrief it in a while with a working example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;You might need to ensure that Java and Maven are installed in your machine/server (Java 8 is the minimum version to be used)&lt;/li&gt;
&lt;li&gt;Create a maven project and add the following dependencies to your pom.xml
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.junit.jupiter&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;junit-jupiter-api&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;5.6.2&amp;lt;/version&amp;gt;
            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;de.retest&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;recheck-web&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.9.0&amp;lt;/version&amp;gt;
            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.seleniumhq.selenium&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;selenium-java&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;3.141.59&amp;lt;/version&amp;gt;
            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;ch.qos.logback&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;logback-classic&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.2.3&amp;lt;/version&amp;gt;
            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;The next thing you would need is an URL or a demo application against which you can test the script. I have created a sample login application which we will consider for this example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Selenium Test
&lt;/h3&gt;

&lt;p&gt;We can write a simple selenium test for the login app. Also, make a note that you should specify whichever driver you are using and the following driver should be made available to execute. In this case, I am using a Chrome driver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.nio.file.Paths;

public class SeleniumTest {
    public WebDriver driver;

    @BeforeEach
    public void setupDriver() {
        System.setProperty("webdriver.chrome.driver","src/test/resources/drivers/chromedriver");
        driver = new ChromeDriver();
    }

    @Test
    public void breakableTest() throws Exception {
        String url = Paths.get("src/test/resources/loginpage.html").toUri().toURL().toString();
        driver.get(url);
        driver.findElement(By.id("username-field")).sendKeys("user");
        driver.findElement(By.id("password-field")).sendKeys("dev");
        driver.findElement(By.id("login-form-submit")).click();

        String result = driver.findElement(By.id("login-success-msg")).getText().equals("You have successfully logged in") ? "Login Pass" : "Login Fail";
        System.out.println(result);
    }

    @AfterEach
    public void windUp(){
        driver.quit();
    }
}

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

&lt;/div&gt;



&lt;p&gt;You could see from the above scenario that we need to explicitly make an assertion to find if the successful login message is displayed. Run this test and you will see that the test will pass. What if there are some UI changes that are made in the new release of your app. Consider the below example where you have the ID attributes 'username-field' and 'password-field'. It is now changed to 'username' and 'password' in the new release of the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form id="login-form"&amp;gt;
        &amp;lt;input type="text" name="username" id="username" class="login-form-field" placeholder="Username"&amp;gt;
        &amp;lt;input type="password" name="password" id="password" class="login-form-field" placeholder="Password"&amp;gt;
        &amp;lt;input type="submit" value="Login" id="login-form-submit"&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But you could see that the selenium test script carries the id as 'username-field' and 'password-field' rather than 'username-field' and 'password-field'. This test would fail with NoSuchElementExeption.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#username"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Unbreakable Selenium Test
&lt;/h3&gt;

&lt;p&gt;recheck-web truly stands to its name 'Unbreakable' where it creates a Golden Master with which it compares the current state. To create a recheck-web test, simply call the RecheckDriver and pass the driver argument to it as how you would do a RemoteWebDriver invocation. It is so simple and you don't need to add anything else. Of course, there are methods like 'startTest', 'cap', 'check, 'capTest' which can be called using RecheckImplementation class but you don't need to worry about that as all these are encompassed in RecheckDriver class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import de.retest.web.selenium.RecheckDriver;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;

import java.nio.file.Paths;
public class UnbreakableSeleniumTest {
    RecheckDriver driver;

    @BeforeEach
    public void setupRecheck() {
        System.setProperty("webdriver.chrome.driver","src/test/resources/drivers/chromedriver");
        driver = new RecheckDriver(new ChromeDriver());
    }

    @Test
    public void unBreakableTest() throws Exception {
        String url = Paths.get("src/test/resources/loginpage.html").toUri().toURL().toString();
        driver.get(url);
        driver.findElement(By.id("username-field")).sendKeys("user");
        driver.findElement(By.id("password-field")).sendKeys("dev");
        driver.findElement(By.id("login-form-submit")).click();
    }

    @AfterEach
    public void windUp(){
        driver.quit();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider the below login HTML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form id="login-form"&amp;gt;
        &amp;lt;input type="text" name="username" id="username-field" class="login-form-field" placeholder="Username"&amp;gt;
        &amp;lt;input type="password" name="password" id="password-field" class="login-form-field" placeholder="Password"&amp;gt;
        &amp;lt;input type="submit" value="Login" id="login-form-submit"&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you run the test it will fail for the first time as you don't have a Golden Master created yet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1591266008491%2Fz5rJn_D-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1591266008491%2Fz5rJn_D-2.png" alt="Screenshot 2020-06-03 at 5.52.56 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the test again and you will see that the test will succeed but with some errors as mentioned below in the picture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1591267745974%2F98D_pSi1-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1591267745974%2F98D_pSi1-.png" alt="Screenshot 2020-06-03 at 5.55.58 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This assures that our present state is compared against the Golden Master. The errors that you see are some metadata and attributes that are compared against the Golden Master which can be ignored by writing them in the recheck.ignore file generated in .retest folder. Add attribute=grid-template-rows and metadata=window.height in the recheck.ignore file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;attribute=grid-template-rows
metadata=window.height
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Re-run the test and it will succeed without any errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1591268180231%2F3AZpV8us0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1591268180231%2F3AZpV8us0.png" alt="Screenshot 2020-06-03 at 6.20.07 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us now change the login HTML and tweak the ID to 'username' and 'password'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form id="login-form"&amp;gt;
        &amp;lt;input type="text" name="username" id="username" class="login-form-field" placeholder="Username"&amp;gt;
        &amp;lt;input type="password" name="password" id="password" class="login-form-field" placeholder="Password"&amp;gt;
        &amp;lt;input type="submit" value="Login" id="login-form-submit"&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run the test against this new change, the execution will not break but it will refer to the Golden Master that is available since the first run and it will compare the similar attributes that were present earlier and make a one-to-one connection, thereby finds the new element without even throwing any exception. Obviously, the test will report with errors (i.e. the locator change) that were found during the execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1591268777651%2Fq2uuGWIWx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1591268777651%2Fq2uuGWIWx.png" alt="Screenshot 2020-06-03 at 10.29.16 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can see the difference that the expected was 'username-field' but the actual ID attribute was 'username'. The same applies to the ID attribute 'password'. It is not a rule that Golden Master always refers to the outcome that was derived from the first run. We need to update the Golden Master to the latest stable UI changes by liaising with the development community. So we could clearly see that there are often changes happening in and out of the script. This might look like Déjà vu to you as recheck-web has a CLI called recheck.cli which is similar to the operations of GIT. It is imperative that every time you cannot manually update the recheck.ignore file to filter the result and to commit or accept the new UI changes to the Golden Master. This is where recheck.cli would help us in speeding up the process.&lt;/p&gt;

&lt;h3&gt;
  
  
  recheck.cli
&lt;/h3&gt;

&lt;p&gt;In order to install and setup the CLI, refer to this &lt;a href="https://docs.retest.de/recheck.cli/setup/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;. To ensure if the recheck is working, restart your CMD/Terminal after the installation and type recheck. It should return with list of options that are available.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usage: recheck [--help] [--version] [COMMAND]
Command-line interface for recheck.
      --help      Display this help message.
      --version   Display version info.
Commands:
  account     Allows to log into and out of your account and show your API key.
  help        Displays help information about the specified command
  commit      Accept specified differences of given test report.
  completion  Generate and display an auto completion script.
  diff        Compare two Golden Masters.
  ignore      Ignore specified differences of given test report.
  show        Display differences of given test report.
  version     Display version info.

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

&lt;/div&gt;



&lt;p&gt;Every recheck test will generate a report in target/test-classes/retest/recheck/YOURTESTNAME.report. You could run this report using the recheck.cli by hitting the following command by navigating to the report folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ recheck show YOURTESTNAME.report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To accept all the recent changes in your test related to ID attributes, you can simply commit all at once by issuing the below command,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ recheck commit --all YOURTESTNAME.report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you go back and check your retest.xml the attributes would have changed from 'username-field' to 'username' and 'password-field' to 'password'. Now that you have updated the Golden Master, you have to update the corresponding test scripts as well else the test would fail because we don't have a history of 'username-field' or 'password-field' anymore. In order to auto-heal, retest has a GUI called review which is an insightful dashboard that can automatically make the relevant changes in Golden Master and in the test script. &lt;/p&gt;

&lt;p&gt;Also, recheck-web has an important feature called virtual ID. It creates the virtual ID for all the states viz. username, password, and login button. If you want your test to be completely unbreakable, using virtual IDs will make your life worry-free. The retestId has to be imported from the package de.retest.web.selenium.By.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import de.retest.web.selenium.RecheckDriver;
import de.retest.web.selenium.By;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import java.nio.file.Paths;

public class UnbreakableSeleniumTest {
    RecheckDriver driver;

    @BeforeEach
    public void setupRecheck() {
        System.setProperty("webdriver.chrome.driver","src/test/resources/drivers/chromedriver");
        driver = new RecheckDriver(new ChromeDriver());
    }

    @Test
    public void unBreakableTest() throws Exception {
        recheck.startTest();
        String url = Paths.get("src/test/resources/loginpage.html").toUri().toURL().toString();
        driver.get(url);
        driver.findElement(By.retestId("usernamefield")).sendKeys("user");
        driver.findElement(By.retestId("passwordfield")).sendKeys("dev");
        driver.findElement(By.retestId("loginformsubmit")).click();
    }

    @AfterEach
    public void windUp(){
        driver.quit();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the recheck-web &lt;a href="https://docs.retest.de/recheck-web/run-your-first-test/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for more insights and you can also pull my sample implementation from &lt;a href="https://github.com/rksainath/autoheal-recheckweb" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>testautomation</category>
      <category>recheckweb</category>
      <category>seleniumwebdriver</category>
    </item>
    <item>
      <title>Hyperledger Fabric (v1.1) Setup on Ubuntu 18.04 — Part III</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Tue, 17 Dec 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/rksainath/hyperledger-fabric-v11-setup-on-ubuntu-1804-part-iii-3hoe</link>
      <guid>https://forem.com/rksainath/hyperledger-fabric-v11-setup-on-ubuntu-1804-part-iii-3hoe</guid>
      <description>&lt;p&gt;In the previous section Part - I we saw about the necessary pre-requisites for running the Hyperledger Fabric and in this final section, we will finally install the essential command-line tools to run the fabric development environment.&lt;/p&gt;

&lt;p&gt;Install Composer-CLI using npm which is the essential aspect of fabric development using composer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g composer-cli&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;We will need Composer Rest Server in order to expose our business network as RESTful APIs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g composer-rest-server&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;In the previous post, you would have seen about Yeoman which is a scaffolding tool that we will be using here in order to pack the application assets related to fabric.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g generator-hyperledger-composer&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;There is an online app called Playground for developing business network applications using hyperledger fabric. If you would like to have a local copy of it just install the package and use it from your local machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g composer-playground&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Create a folder called fabric-dev-servers and navigate to the folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir ~/fabric-dev-servers cd ~/fabric-dev-servers&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Using CURL command fetch fabric-dev-servers tar file and unpack it using tar -xvf by passing the file to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.tar.gz tar -xvf fabric-dev-servers.tar.gz&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Unzipping the folder will give you a list of files out of which you have to run &lt;code&gt;downloadFabric.sh&lt;/code&gt; and prior to this kindly set the environment for the desired fabric version as mentioned in the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/fabric-dev-servers export FABRIC_VERSION=hlfv12 ./downloadFabric.sh&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;downloadFabric.sh&lt;/code&gt; would install a list of docker images required for running the fabric. You can check the list of images using the command docker images. Ensure that you have all the images in the list as mentioned below in the screenshot.&lt;/p&gt;

&lt;p&gt;Thats it and you are done. Before finishing there are few things to be noted. If you are using Ubuntu as a cloud instance or connecting a remote Ubuntu server, ensure that you dont do the fabric installation as a root user. Kindly create a new user and change your profile to that new user that you have created. At times if you dont have the right to perform or run docker commands, use sudo and execute it.&lt;/p&gt;

</description>
      <category>hyperledger</category>
    </item>
    <item>
      <title>Hyperledger Fabric (v1.1) Setup on Ubuntu 18.04 — Part II</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Wed, 11 Dec 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/rksainath/hyperledger-fabric-v11-setup-on-ubuntu-1804-part-ii-1ehl</link>
      <guid>https://forem.com/rksainath/hyperledger-fabric-v11-setup-on-ubuntu-1804-part-ii-1ehl</guid>
      <description>&lt;p&gt;This part will talk about the pre-requisites for installing Hyperledger Composer. If you need assistance on the choice of platform, refer to Part - I for more details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;NodeJS&lt;/strong&gt; is essential for hyperledger composer as the development will be based on javascript. Install version 8.x as fabric relies on it and don't install the latest version of the node. To make it more switchable between the latest and version 8.x, one could install Node Version Manager so that you dont need to stick to 8.x all the time and use only when the fabric demands it.&lt;/p&gt;

&lt;p&gt;Open up your terminal and run the below-mentioned command to install NVM. Note: Ensure that you have CURL installed prior to running this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Once you are done with the installation, run the following command to install node 8.x. If you dont mention the version, the latest stable version will be installed. Once the node is installed, tell nvm to use 8 as the default node environment. Finally, run the last line to check if you have installed version 8.x. For more details refer &lt;a href="https://github.com/creationix/nvm"&gt;here&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;nvm install 8 nvm use 8 node -v&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt; is by default available in all major GNU/Linux distros. If your choice of the distro is not listed or new then check &lt;a href="https://docs.python.org/2.7/using/unix.html#on-linux"&gt;here&lt;/a&gt; on the steps to install python in it. It is essential that you install Python 2.7.x and not Python 3.x.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Git&lt;/strong&gt; is one of the most widely used source control management feature and it can be installed by running the command below. For more details on git, refer &lt;a href="https://git-scm.com/download/linux"&gt;here&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;sudo apt-get install git&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Yeoman&lt;/strong&gt; is a client-side web scaffolding tool and it is primarily used by fabric to render hyperledger composer generator that is scaffolded using yeoman. Check the docs &lt;a href="https://yeoman.io/learning/"&gt;here&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;npm install -g yo&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Docker&lt;/strong&gt; is a container that relieves one from worrying about the dependencies for the application and wraps up all the essentials that are needed to run your application as one docker image. Docker CE (Community Edition) is required to be installed and there are a series of steps involved while installing Docker for Ubuntu. Check the documentation &lt;a href="https://docs.docker.com/install/linux/docker-ce/ubuntu/"&gt;here&lt;/a&gt; for more clarity and follow the instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visual Studio Code&lt;/strong&gt; is the most recommended IDE for fabric development as we have the hyperledger composer plugin for VS Code. Once you install the editor, go to extensions and search for hyperledger composer plugin and install. You can also find the plugin in &lt;a href="https://marketplace.visualstudio.com/items?itemName=HyperledgerComposer.composer-support-client"&gt;Visual Studio Marketplace&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;sudo snap install --classic code&amp;lt;/span&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;In the next Part - III, we shall see about the installation of Hyperledger Fabric tools.&lt;/p&gt;

</description>
      <category>hyperledger</category>
    </item>
    <item>
      <title>Hyperledger Fabric (v1.1) Setup on Ubuntu 18.04 — Part I</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Mon, 02 Dec 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/rksainath/hyperledger-fabric-v11-setup-on-ubuntu-1804-part-i-4177</link>
      <guid>https://forem.com/rksainath/hyperledger-fabric-v11-setup-on-ubuntu-1804-part-i-4177</guid>
      <description>&lt;p&gt;This post is going to talk about the installation of &lt;strong&gt;Hyperledgers&lt;/strong&gt; tool called &lt;strong&gt;Hyperledger Composer&lt;/strong&gt; which is used to create business networks and enables business analysts and developers to create smart contracts and blockchain applications.&lt;/p&gt;

&lt;p&gt;Before we jump into the installation of the composer tool, I would like to give you clarity on the choice of the platform that best fits for the development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform Support
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;

&lt;p&gt;If you own a Windows machine then I would recommend that you install a virtual machine like &lt;strong&gt;VirtualBox&lt;/strong&gt; / &lt;strong&gt;VMWare&lt;/strong&gt; and then spin an Ubuntu image in it. Since the fabric heavily relies on the Unix environment and docker it is suggested that we use a Linux variant for installing the fabric. Native Windows support is not there yet for Hyperledger Fabric as of (April 2019)&lt;/p&gt;

&lt;h3&gt;
  
  
  MacOS
&lt;/h3&gt;

&lt;p&gt;If you own a Mac OS then it is not going to be a problem as the environment itself is based on Unix. The only aspect that you have to ensure is sufficient disk space&lt;/p&gt;

&lt;h3&gt;
  
  
  Ubuntu
&lt;/h3&gt;

&lt;p&gt;If you are on Ubuntu then it is a cake-walk for you who enjoys the perks of being a Linux user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Infrastructure
&lt;/h2&gt;

&lt;p&gt;Cloud platform comes to the rescue irrespective of what operating system you run. It is so handy that you can just ssh to the instance that you have created in the cloud. There are many providers viz. Amazon Web Services, Microsoft Azure, Google Cloud Platform, and so on. You can refer to this &lt;a href="https://partners.ubuntu.com/find-a-partner?programme=certified-public-cloud"&gt;page&lt;/a&gt; for detailed support by cloud providers for Ubuntu. I am not going to guide you through in choosing the cloud provider nor in creating an instance but I can show you a sample on AWS as a reference.&lt;/p&gt;

&lt;p&gt;Kindly visit the &lt;a href="https://aws.amazon.com/marketplace/pp/B07CQ33QKV"&gt;link&lt;/a&gt; to check the AWS marketplace for subscribing to Ubuntu 18.04 LTS Bionic image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AbD9olTE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204834929/-k1ROTlz-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AbD9olTE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204834929/-k1ROTlz-.png" alt="" width="880" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose the T2-medium tier as the option while choosing the image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ABOhCU-x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204836283/Y5a4l6sey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ABOhCU-x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204836283/Y5a4l6sey.png" alt="" width="536" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;T2 medium is required as the Fabric needs at least 4GB of memory. Kindly note that charges for t2.medium may vary from other models. Please ensure that you check the cost per hour before spinning as the running EC2-instance may incur charges. You can refer to the EC2 documentation &lt;a href="https://aws.amazon.com/ec2/instance-types/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rA6LO7RQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204837825/MvKmAKwyG.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rA6LO7RQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204837825/MvKmAKwyG.png" alt="" width="663" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is important to note that in the sequence of subscribing to the t2.medium ec2 instance you will be landed on a specific page where you will be asked to define the security group for the instance to communicate with the outside world. By default, SSH will be open, adding to this you need to open up all the TCP ports for your IP (NOTE: It is a risk to open TCP ports to all IPs and be specific on which IP you are going to use). Kindly ensure that you refer the documentation/experts in order to define the security group settings.&lt;/p&gt;

&lt;p&gt;Now that we are done with the choice of platform, in the following series we can start installing the pre-requisites.&lt;/p&gt;

</description>
      <category>hyperledger</category>
    </item>
    <item>
      <title>Blockchain vs Distributed Database</title>
      <dc:creator>Sainath Ramanathan</dc:creator>
      <pubDate>Sun, 10 Mar 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/rksainath/blockchain-vs-distributed-database-4amd</link>
      <guid>https://forem.com/rksainath/blockchain-vs-distributed-database-4amd</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BWcFzNHi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204787709/6pj0roOkn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BWcFzNHi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204787709/6pj0roOkn.gif" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This debate has been prevalent since the inception of blockchain. Always there is a counter-argument whenever people talk about the way we handle data either it is distributed or centralized. I am not going to judge between the two but give you an overview of how it will operate with different use cases.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oYvGbNXJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204791824/2b5_6CqeK.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oYvGbNXJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204791824/2b5_6CqeK.gif" alt="" width="289" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider you have a system where you need to pass around the document/digital asset from one entity to another. It should be a system where all the entities should be known to each other. This is where distributed databases come in to play. Some of the features a system must possess in order to achieve the distribution of data,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Periodic synchronization of data&lt;/li&gt;
&lt;li&gt;Limits the access to all the entities and defines the access privileges&lt;/li&gt;
&lt;li&gt;Universal update of data across the system&lt;/li&gt;
&lt;li&gt;Ability to handle multiple users and provide the same data as served to others&lt;/li&gt;
&lt;li&gt;Depends on an Admin to monitor and operate the system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, based on the above it is clear that distributed data is apt for the scenarios where you share the data among known-groups. For example, if IBM has a group of companies that it owns, it is imperative that they form a distributed database among them. This is because you know all the entities participating and there is less chance that the data may get tampered (unless there is a DDOS) and it is governed by a database admin who has the strong privileges to handle the data. This is where blockchain is unnecessary in terms of the trust but in terms of data tamper and security, it is worthy that you have it implemented. Another example would be the CRUD application which will never need blockchain unless there are multiple players involved in it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blockchain
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wOsSeDun--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204793800/eoXDW2P8r.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wOsSeDun--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1650204793800/eoXDW2P8r.gif" alt="" width="550" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The word Blockchain is a cliche now. Every company and its experts are constantly exploring ways to implement blockchain in their business. It is a buzzword that is being used in every hackathon, seminars, workshops, and even in tea-shops. Thanks to Satoshi Nakamoto that he/she is anonymous else their mailbox would be bombarded with queries. Blockchain is more like a suit. It is not fit for all but tailored for specific needs. One cant compare an ocean to a glass of water similarly blockchain is not a solution to all the cases. One has to use it worthy for the real challenge that needs to be addressed among the heterogeneous group.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we focus blockchain for heterogeneous groups?
&lt;/h2&gt;

&lt;p&gt;Blockchains verdict runs on transparency, tamper-proof and autonomous systems. When I mean heterogeneous there involves multiple players who dont trust each other. You could have financial institutions, educational, internet, media, and so on. This cross-contamination and sharing of data among them can be achieved by blockchain. Blockchain will set up a node for every participant and group them to specific channels where they can transfer data. The data here being a unique ciphered content where non-trusting parties can check the authenticity of the data received by verifying with the hash of original data. This not only introduces transparency and tamper-proof ingredients but also a ledger that will be maintained to maintain the audit trail of all the transactions that have happened. There is no need for any middleman/admins to control the data as we have contracts (software code) that are written as business logic which will take care of the transfer.&lt;/p&gt;

&lt;p&gt;The inference is, one cant vote which is best simply by putting the technology in front but the use case is the one that will decide which is better.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>database</category>
    </item>
  </channel>
</rss>
