<?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: Sumit Bhanushali</title>
    <description>The latest articles on Forem by Sumit Bhanushali (@sumitbhanushali).</description>
    <link>https://forem.com/sumitbhanushali</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%2F752938%2F3356d359-d77f-44ab-bf64-a5a1f14775aa.png</url>
      <title>Forem: Sumit Bhanushali</title>
      <link>https://forem.com/sumitbhanushali</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sumitbhanushali"/>
    <language>en</language>
    <item>
      <title>Production Ready NodeJS build using Docker and npm</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Tue, 12 Dec 2023 07:34:19 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/production-ready-nodejs-build-using-docker-and-npm-3mp4</link>
      <guid>https://forem.com/sumitbhanushali/production-ready-nodejs-build-using-docker-and-npm-3mp4</guid>
      <description>&lt;p&gt;An app with a smooth deployment process is reliable and has fewer bugs because it is easy to release fixes and is easier to set up in any environment. An app can lose all its charm if it is not reliable. When users want your app to work, it should work.&lt;br&gt;
To set up a smooth deployment process, we will divide our process into three stages which will benefit Developers, DevOps and Users alike.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Build&lt;br&gt;
The build Stage is when we are done with developing code and are confident for deployment. We thus run a build command that outputs an executable file that cannot be modified by us.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Release&lt;br&gt;
Release Stage is where we combine our build with config which makes the app able to run. These releases should be tagged with a unique ReleaseID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run&lt;br&gt;
Run Stage is where we run our release and make our app accessible to the outside world.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These stages should be strictly separated and any code change should trigger a new build, release and run stage. The Run stage should be as simple as possible. Any process or system restart can easily rerun our run stage without requiring manual intervention. This also simplifies rolling back to the previous release when required. Let's start with the first stage&lt;/p&gt;
&lt;h3&gt;
  
  
  Build
&lt;/h3&gt;

&lt;p&gt;We will use Docker to build our app. We will be able to use the image generated from docker to deploy on any machine where docker is installed.&lt;br&gt;
We will need a few npm scripts which will be used in our Dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"prisma:generate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prisma generate"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node .dist/index.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we will create &lt;code&gt;Dockerfile&lt;/code&gt;. We will use a multi-stage build technique to keep our image size minimal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:20-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="nt"&gt;--only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run prisma:generate

&lt;span class="c"&gt;##### STAGE 2 #####&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:20-alpine&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /usr/src/app/.dist ./.dist&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /usr/src/app/node_modules ./node_modules&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /usr/src/app/package.json ./package.json&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;These commands &lt;code&gt;RUN npm run build &amp;amp;&amp;amp; npm run prisma:generate&lt;/code&gt; is where our Typescript code gets converted to Javascript and necessary prisma client files will be created. &lt;/p&gt;

&lt;p&gt;In Stage 2, we will only copy files from &lt;code&gt;.dist&lt;/code&gt; folder and discard typescript files.&lt;br&gt;
This config.env file will be different for different environments like UAT, Production, etc. We will be required to manually create/update this file before creating a Docker container.&lt;/p&gt;

&lt;p&gt;We will use this command to build a Docker image, we are using the version from our package version to tag our images. In this case, our image name will be bloggo:0.1.0&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker image build &lt;span class="nt"&gt;-t&lt;/span&gt; bloggo:&lt;span class="si"&gt;$(&lt;/span&gt;node &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="se"&gt;\"&lt;/span&gt;require&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'./package.json'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;.version&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can further simplify the build process by introducing some npm scripts.&lt;/p&gt;

&lt;p&gt;Build image by just running &lt;code&gt;npm run build&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"build:image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docker image build -t bloggo:$(node -p &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;require('./package.json').version&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;) ."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upgrade the version accordingly and build an image. Note that npm version  requires that all changes are already committed and this command will create a new commit with the version number as the tag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"build:major"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version major &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build:minor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version minor &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build:patch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version patch &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full npm scripts for reference&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prisma:generate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prisma generate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node .dist/index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start:dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nodemon --exec node -r ts-node/register --env-file=config.env index.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docker image build -t bloggo:$(node -p &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;require('./package.json').version&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;) ."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:major"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version major &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:minor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version minor &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:patch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version patch &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Release
&lt;/h3&gt;

&lt;p&gt;Release = Build + Config&lt;/p&gt;

&lt;p&gt;This command creates a Release version for us. Here Docker's ContainerID can be treated as ReleaseID. We are using &lt;code&gt;--env-file&lt;/code&gt; to load &lt;code&gt;config.env&lt;/code&gt; file in our container&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container create &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 &lt;span class="nt"&gt;--env-file&lt;/span&gt; config.env bloggo:0.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run
&lt;/h3&gt;

&lt;p&gt;To fetch ContainerID, which we will use to &lt;code&gt;run&lt;/code&gt; our container&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start container and add restart policy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container start a897dbba5329 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker update &lt;span class="nt"&gt;--restart&lt;/span&gt; unless-stopped a897dbba5329
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this setup, we will be easily be able to generate deployment builds and deploy to any number of servers with just few changes in config (if required) reliably&lt;/p&gt;

&lt;p&gt;Link to the project that will be used in this post: &lt;a href="https://github.com/sumitbhanushali/bloggo"&gt;https://github.com/sumitbhanushali/bloggo&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Production Ready NodeJS build using Docker and npm</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Tue, 12 Dec 2023 07:34:18 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/production-ready-nodejs-build-using-docker-and-npm-2c59</link>
      <guid>https://forem.com/sumitbhanushali/production-ready-nodejs-build-using-docker-and-npm-2c59</guid>
      <description>&lt;p&gt;An app with a smooth deployment process is reliable and has fewer bugs because it is easy to release fixes and is easier to set up in any environment. An app can lose all its charm if it is not reliable. When users want your app to work, it should work.&lt;br&gt;
To set up a smooth deployment process, we will divide our process into three stages which will benefit Developers, DevOps and Users alike.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Build&lt;br&gt;
The build Stage is when we are done with developing code and are confident for deployment. We thus run a build command that outputs an executable file that cannot be modified by us.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Release&lt;br&gt;
Release Stage is where we combine our build with config which makes the app able to run. These releases should be tagged with a unique ReleaseID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run&lt;br&gt;
Run Stage is where we run our release and make our app accessible to the outside world.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These stages should be strictly separated and any code change should trigger a new build, release and run stage. The Run stage should be as simple as possible. Any process or system restart can easily rerun our run stage without requiring manual intervention. This also simplifies rolling back to the previous release when required. Let's start with the first stage&lt;/p&gt;
&lt;h3&gt;
  
  
  Build
&lt;/h3&gt;

&lt;p&gt;We will use Docker to build our app. We will be able to use the image generated from docker to deploy on any machine where docker is installed.&lt;br&gt;
We will need a few npm scripts which will be used in our Dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"prisma:generate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prisma generate"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node .dist/index.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we will create &lt;code&gt;Dockerfile&lt;/code&gt;. We will use a multi-stage build technique to keep our image size minimal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:20-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="nt"&gt;--only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run prisma:generate

&lt;span class="c"&gt;##### STAGE 2 #####&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:20-alpine&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /usr/src/app/.dist ./.dist&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /usr/src/app/node_modules ./node_modules&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /usr/src/app/package.json ./package.json&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;These commands &lt;code&gt;RUN npm run build &amp;amp;&amp;amp; npm run prisma:generate&lt;/code&gt; is where our Typescript code gets converted to Javascript and necessary prisma client files will be created. &lt;/p&gt;

&lt;p&gt;In Stage 2, we will only copy files from &lt;code&gt;.dist&lt;/code&gt; folder and discard typescript files.&lt;br&gt;
This config.env file will be different for different environments like UAT, Production, etc. We will be required to manually create/update this file before creating a Docker container.&lt;/p&gt;

&lt;p&gt;We will use this command to build a Docker image, we are using the version from our package version to tag our images. In this case, our image name will be bloggo:0.1.0&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker image build &lt;span class="nt"&gt;-t&lt;/span&gt; bloggo:&lt;span class="si"&gt;$(&lt;/span&gt;node &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="se"&gt;\"&lt;/span&gt;require&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'./package.json'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;.version&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can further simplify the build process by introducing some npm scripts.&lt;/p&gt;

&lt;p&gt;Build image by just running &lt;code&gt;npm run build&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"build:image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docker image build -t bloggo:$(node -p &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;require('./package.json').version&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;) ."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upgrade the version accordingly and build an image. Note that npm version  requires that all changes are already committed and this command will create a new commit with the version number as the tag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"build:major"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version major &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build:minor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version minor &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build:patch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version patch &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full npm scripts for reference&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prisma:generate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prisma generate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node .dist/index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start:dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nodemon --exec node -r ts-node/register --env-file=config.env index.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docker image build -t bloggo:$(node -p &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;require('./package.json').version&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;) ."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:major"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version major &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:minor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version minor &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:patch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm version patch &amp;amp;&amp;amp; npm run build:image"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Release
&lt;/h3&gt;

&lt;p&gt;Release = Build + Config&lt;/p&gt;

&lt;p&gt;This command creates a Release version for us. Here Docker's ContainerID can be treated as ReleaseID. We are using &lt;code&gt;--env-file&lt;/code&gt; to load &lt;code&gt;config.env&lt;/code&gt; file in our container&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container create &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 &lt;span class="nt"&gt;--env-file&lt;/span&gt; config.env bloggo:0.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run
&lt;/h3&gt;

&lt;p&gt;To fetch ContainerID, which we will use to &lt;code&gt;run&lt;/code&gt; our container&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start container and add restart policy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container start a897dbba5329 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker update &lt;span class="nt"&gt;--restart&lt;/span&gt; unless-stopped a897dbba5329
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this setup, we will be easily be able to generate deployment builds and deploy to any number of servers with just few changes in config (if required) reliably&lt;/p&gt;

&lt;p&gt;Link to the project that will be used in this post: &lt;a href="https://github.com/sumitbhanushali/bloggo" rel="noopener noreferrer"&gt;https://github.com/sumitbhanushali/bloggo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>node</category>
      <category>typescript</category>
    </item>
    <item>
      <title>12 Factor App in NodeJS Part 1 (1-4)</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Thu, 07 Dec 2023 10:02:23 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/12-factor-app-in-nodejs-part-1-1-4-5gp2</link>
      <guid>https://forem.com/sumitbhanushali/12-factor-app-in-nodejs-part-1-1-4-5gp2</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/sumitbhanushali/12-factor-app-in-nodejs-part-0-intro-m0a"&gt;Part 0&lt;/a&gt;, we got an overview of the 12-factor app methodology and its importance in building a scalable and reliable backend. In this Part, we will learn in detail about the first 4 factors and simultaneously implement them by building a blogging platform using NodeJS &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Codebase
&lt;/h2&gt;

&lt;p&gt;Nowadays, everyone is familiar with version control systems aka VCS, such as Git, Mercurial, or Subversion, Git being the most popular one. It has become second nature to us that the first thing we do after initializing our project is run &lt;code&gt;git init &amp;amp;&amp;amp; git add . &amp;amp;&amp;amp; git commit -m "Initial commit"&lt;/code&gt;. To understand how important VCS is let's assume we don't know about VCS or something like VCS doesn't even exist.&lt;/p&gt;

&lt;p&gt;Let's take 4 scenarios to understand how difficulty escalates exponentially&lt;br&gt;
1) Working Solo on a Project with Single Deployment&lt;br&gt;
2) Working Solo on a Project with Multiple Versions and Deployments&lt;br&gt;
3) Working in a Team of 4 with a Single Version and Deployment&lt;br&gt;
4) Working in a Team of 4 with Multiple Versions and Deployments&lt;/p&gt;

&lt;p&gt;Here, deployment means a version of the codebase. Single Deployment means only one version of the codebase that will be deployed. Multiple Deployments means multiple versions(including client-specific) of codebase in multiple environments(staging, UAT, production)&lt;/p&gt;
&lt;h3&gt;
  
  
  Scenario 1: Working Solo on a Project with Single Deployment
&lt;/h3&gt;

&lt;p&gt;As a solo developer without version control, working on a project with a single deployment becomes a risky situation. Any code changes made are irreversible, and there's no safety net in case of errors. If a bug is introduced, there's no straightforward way to revert to a previous, stable state. The lack of versioning makes it challenging to track changes over time, and it's easy to lose sight of the project's evolution.&lt;/p&gt;

&lt;p&gt;Collaboration with past iterations is impossible, making it difficult to understand the reasoning behind certain decisions or to revisit successful implementations. The absence of branching and merging capabilities means that experimenting with new features or fixes could disrupt the entire codebase.&lt;/p&gt;

&lt;p&gt;Deployments are a nerve-wracking process. If an issue arises during deployment, rolling back to a working state is a manual and error-prone task. Without a VCS, there are no efficient means of documenting the deployed versions or managing configurations for different environments.&lt;/p&gt;
&lt;h3&gt;
  
  
  Scenario 2: Working Solo on a Project with Multiple Versions and Deployments
&lt;/h3&gt;

&lt;p&gt;In this scenario, the absence of version control worsens the challenges faced in the first scenario. Managing multiple versions and deployments without VCS becomes a logistical nightmare. Keeping track of different code states for various features or environments is practically impossible.&lt;/p&gt;

&lt;p&gt;Each deployment is a high-stakes endeavor, as there is no systematic way to isolate changes specific to a version or deployment. Debugging becomes a herculean task, and the risk of introducing new bugs while fixing existing issues looms large. Without branching, trying out experimental features or implementing temporary fixes without affecting the main codebase becomes nearly impossible.&lt;/p&gt;

&lt;p&gt;Documentation is limited to external notes or comments within the code, making it hard to understand the rationale behind specific versions or deployments. Coordinating changes across different branches or versions requires meticulous manual effort, leading to a high probability of errors.&lt;/p&gt;
&lt;h3&gt;
  
  
  Scenario 3: Working in a Team of 4 with Single Version and Deployment
&lt;/h3&gt;

&lt;p&gt;Without version control in a team setting, collaboration turns chaotic. Coordinating efforts among team members becomes a communication-heavy process, relying on constant updates and manual file sharing. The risk of overwriting each other's work is ever-present, and resolving conflicts is an arduous manual task.&lt;/p&gt;

&lt;p&gt;There's no clear history of changes, making it difficult to attribute modifications to specific team members, there will be blame games of faulty code as we won't be able to pinpoint who introduced the faulty code. Debugging and troubleshooting are cumbersome, as there's no easy way to identify when and why a particular change was made.&lt;/p&gt;

&lt;p&gt;Deployment is a risky and unpredictable process, with no efficient rollback mechanism. Coordinating releases requires meticulous planning and synchronization among team members, increasing the likelihood of errors and downtime.&lt;/p&gt;
&lt;h3&gt;
  
  
  Scenario 4: Working in a Team of 4 with Multiple Versions and Deployments
&lt;/h3&gt;

&lt;p&gt;In a team setting with multiple versions and deployments but without version control, the challenges escalate exponentially. Collaboration becomes a logistical nightmare, with each team member potentially working on a different version or deployment. Coordinating changes and ensuring a cohesive codebase is a constant struggle.&lt;/p&gt;

&lt;p&gt;Without branching and merging capabilities, integrating features or fixes from different team members becomes an error-prone process. The risk of introducing conflicts and breaking the codebase during integration is high. Keeping track of changes across multiple branches or versions requires meticulous manual effort and is prone to oversight.&lt;/p&gt;

&lt;p&gt;Deployments are high-stakes events, and rolling back to a stable state in case of issues is a manual and time-consuming task. The lack of versioning makes it challenging to manage configurations for different environments, leading to potential deployment errors.&lt;/p&gt;
&lt;h2&gt;
  
  
  It was just a Nightmare
&lt;/h2&gt;

&lt;p&gt;To sum it up, without version control, it's like navigating a coding maze with a blindfold. Adding a version control system is like turning on the lights — suddenly, everything just clicks. I hope after reading this, your appreciation for VCS increases tenfold&lt;/p&gt;

&lt;p&gt;Now that we know what it's like without VCS, let's create our project and initialize it with git. Our project will be a simple blog application that will be built using ExpressJS, Typescript and MySQL. We will name our project will be bloggo.&lt;/p&gt;
&lt;h3&gt;
  
  
  Let The Coding Begin
&lt;/h3&gt;

&lt;p&gt;Create a Project folder with README.md&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;bloggo &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;bloggo &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;touch &lt;/span&gt;README.md &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"# Bloggo &lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Simple Blog Application"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initialize Git Repo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
git init &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git add &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"initial commit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Link to commit for changes up to this section &lt;a href="https://github.com/sumitbhanushali/bloggo/commit/a5f14218eab0fb5a84fdf1e31fe31965925e81d1" rel="noopener noreferrer"&gt;https://github.com/sumitbhanushali/bloggo/commit/a5f14218eab0fb5a84fdf1e31fe31965925e81d1&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Dependencies
&lt;/h2&gt;

&lt;p&gt;12 Factor app is easy to setup and run. This will be possible when all dependencies are declared in the dependency declaration manifest. These dependencies will be isolated i.e these dependencies will only apply to the current app and no global or system-wide package will be accessible inside it unless it is explicitly declared in the dependency declaration manifest.&lt;br&gt;
This reduces friction to setup project on a developer's machine or even on production and leads to increased productivity and thus a better app will be delivered.&lt;br&gt;
NodeJS has few popular package managers available like npm, pnpm and yarn. We will be using npm since it is the official package manager of NodeJS and most developers are already well-versed with it&lt;/p&gt;

&lt;p&gt;This generates a default &lt;strong&gt;&lt;em&gt;package.json&lt;/em&gt;&lt;/strong&gt; file which will be used by npm to store metadata, dependencies and scripts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use express to create our app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don't want node_modules to be committed to git since it will unnecessarily increase our repo size which will make it longer to clone&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"node_modules"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our final package.json file will look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bloggo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Simple Blog Application"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ISC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.18.2"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Link to commit for changes in this post &lt;a href="https://github.com/sumitbhanushali/bloggo/commit/a91c1424aa8a7279740338276af563bf1c0c5ee6" rel="noopener noreferrer"&gt;https://github.com/sumitbhanushali/bloggo/commit/a91c1424aa8a7279740338276af563bf1c0c5ee6&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Config
&lt;/h2&gt;

&lt;p&gt;An app’s config is everything likely to vary between deploys (staging, production, developer environments, etc) which are credentials to external services such as Database(MySQL, Redis), Cloud Providers or External APIs like Twitter, Dropbox, etc. &lt;br&gt;
A beginner might hardcode such config in a codebase or might create separate versions of such file for each deployment. Such a person might not be aware of problems that can arise because of this. If such configs get in the wrong hands (hacker or fresher), that person can bring down the whole system by deleting the database or misconfigure something accidentally or purposely.&lt;br&gt;
Configs should never be committed to VCS even if it is a private repository. A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials.&lt;/p&gt;

&lt;p&gt;Some teams maintain a config file with defaults and edit this file manually at the server level according to environment needs. This is a good approach but there is still room for errors. &lt;/p&gt;

&lt;p&gt;Another approach is to batch config into named groups (often called “environments”) named after specific deploys, such as the development, test, and production environments. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as staging or QA. As the project grows further, developers may add their special environments like joes-staging, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle.&lt;/p&gt;

&lt;p&gt;The best way is to make use of environment variables which are provided by every OS out there. In NodeJS, you can access these environment variables using process.env.ENV_VARIABLE where ENV_VARIABLE can be any variable name. &lt;code&gt;dotenv&lt;/code&gt; is a popular package to simplify using environment variables which is used by almost every NodeJS project out there. From Node v20.6.0, support for reading environment variables from &lt;code&gt;.env&lt;/code&gt; file is added which removes the dependency from &lt;code&gt;dotenv&lt;/code&gt;` package. &lt;/p&gt;

&lt;p&gt;We can choose to add this file into .gitignore and pass this file manually across team members or provide a default file for staging and editing this file on sensitive(internet-facing) environments&lt;/p&gt;

&lt;p&gt;environment variables in NodeJS are accessed from process.env &lt;br&gt;
&lt;code&gt;&lt;/code&gt;`ts&lt;br&gt;
//index.js&lt;/p&gt;

&lt;p&gt;console.log(process.env.foo);&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;node only supports reading environment variables from files having .env extension &lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
//config.env&lt;/p&gt;

&lt;p&gt;foo=bar&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;add file to .gitignore, as we don't want to commit this file in our git&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
echo "config.env" &amp;gt;&amp;gt; .gitignore&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;we need to pass --env-file=config.env for NodeJS process to read our .env file&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`bash&lt;br&gt;
node --env-file=config.env index.js&lt;/p&gt;

&lt;h2&gt;
  
  
  `&lt;code&gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Link to commit for changes in this post &lt;a href="https://github.com/sumitbhanushali/bloggo/commit/56c3e46168a9146912db2814cb0030905d3d8300" rel="noopener noreferrer"&gt;https://github.com/sumitbhanushali/bloggo/commit/56c3e46168a9146912db2814cb0030905d3d8300&lt;/a&gt;&lt;br&gt;
references: &lt;a href="https://nodejs.org/en/blog/release/v20.6.0" rel="noopener noreferrer"&gt;https://nodejs.org/en/blog/release/v20.6.0&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Backing Services
&lt;/h2&gt;

&lt;p&gt;A backing service is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as MySQL or MongoDB), messaging/queueing systems (such as RabbitMQ or Kafka), caching systems (such as Redis).&lt;/p&gt;

&lt;h3&gt;
  
  
  Make your app scalable
&lt;/h3&gt;

&lt;p&gt;If you want your app to be scalable, you should keep components as decoupled as possible. Components like API Servers, Database, Message Brokers, Caching Servers, etc. This way you can independently scale them according to the application's needs. Our API Server should be prepared from the beginning for such changes to come Otherwise, It would take months of refactoring efforts depending on how big your codebase is.&lt;/p&gt;

&lt;p&gt;Your App should make no distinction between local and the third party services. Each component must be pluggable where you can attach and detach them at your will. These components can be accessed via URL or some type of credentials which should be stored in the Config. This way, if your business needs require you to swap your local MySQL database instance to one managed by a third party service such as Amazon RDS, it would just require a change in URL stored in Config. The same applies to if you need to shard your database or need to replace a faulty database.&lt;/p&gt;

&lt;p&gt;In previous posts, we initialized git repository, and did setup for adding dependencies and config. For this post, we require CRUD App Setup, scope of which is outside of this post hence I have created another &lt;a href="https://dev.to/sumitbhanushali/setup-crud-app-express-typescript-and-mysql-2knh"&gt;post&lt;/a&gt; where I have added detailed setup instructions on how to setup Typescript with ExpressJS and Prisma as ORM which will communicate with our database. We will focus on connecting database using URL in this post using Prisma. You can checkout code at commit &lt;a href="https://github.com/sumitbhanushali/bloggo/commit/03792df70faf7182c7ff88c62d9f5426d27627a9" rel="noopener noreferrer"&gt;https://github.com/sumitbhanushali/bloggo/commit/03792df70faf7182c7ff88c62d9f5426d27627a9&lt;/a&gt; and continue with below steps&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npm install prisma --save-dev&lt;br&gt;
npx prisma init --datasource-provider mysql&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will generate prisma folder in our root directory where in schema.prisma will contain database connection details and prisma models which will be used to create/update tables in our database. We will add two models in schema.prisma&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`ts&lt;br&gt;
model User {&lt;br&gt;
  id        Int      &lt;a class="mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt; &lt;a class="mentioned-user" href="https://dev.to/default"&gt;@default&lt;/a&gt;(autoincrement())&lt;br&gt;
  email     String   &lt;a class="mentioned-user" href="https://dev.to/unique"&gt;@unique&lt;/a&gt;&lt;br&gt;
  name      String?&lt;br&gt;
  blogs     Blog[]&lt;br&gt;
  createdAt DateTime &lt;a class="mentioned-user" href="https://dev.to/default"&gt;@default&lt;/a&gt;(now())&lt;br&gt;
  updatedAt DateTime @updatedAt&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;model Blog {&lt;br&gt;
  id        Int      &lt;a class="mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt; &lt;a class="mentioned-user" href="https://dev.to/default"&gt;@default&lt;/a&gt;(autoincrement())&lt;br&gt;
  title     String&lt;br&gt;
  content   String?&lt;br&gt;
  published Boolean  &lt;a class="mentioned-user" href="https://dev.to/default"&gt;@default&lt;/a&gt;(false)&lt;br&gt;
  author    User     @relation(fields: [authorId], references: [id])&lt;br&gt;
  authorId  Int&lt;br&gt;
  createdAt DateTime &lt;a class="mentioned-user" href="https://dev.to/default"&gt;@default&lt;/a&gt;(now())&lt;br&gt;
  updatedAt DateTime @updatedAt&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This model files are self-explanatory. You can check more about prisma model here: &lt;a href="https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference" rel="noopener noreferrer"&gt;https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference&lt;/a&gt;&lt;br&gt;
Next step is to execute prisma script to run migration which will create these model files inside our database. But before this we need to setup our mysql instance&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`bash&lt;br&gt;
docker pull mysql&lt;/p&gt;

&lt;p&gt;docker run -d --name mysqldb -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
This will pull mysql image from docker hub and create container from it, we have set container name as &lt;code&gt;mysqldb&lt;/code&gt; and root password as &lt;code&gt;password&lt;/code&gt;. Our db will listen on port 3306&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`bash&lt;br&gt;
docker exec -it mysqldb sh&lt;/p&gt;

&lt;p&gt;mysql -u root -p &lt;br&gt;
// enter "password" when prompted&lt;/p&gt;

&lt;p&gt;create database bloggo;&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
This way we can attach to our db container and execute our bash command to connect to mysql and create database named "bloggo". type &lt;code&gt;exit&lt;/code&gt; to exit from mysql and container respectively&lt;br&gt;
We will update our environment variable to our credentials in config.env file&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
DATABASE_URL="mysql://root:password@localhost:3306/bloggo"&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next we will execute prisma script to run migrations, this command also generates prisma client files which comes in handy when using ORM&lt;br&gt;
&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npx prisma migrate dev --name init&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;You can now check that tables have been connected by connecting to mysql instance. Run this commands after connecting to mysql instance&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`bash&lt;br&gt;
use bloggo;&lt;br&gt;
show tables;&lt;/p&gt;

&lt;p&gt;describe Blog;&lt;br&gt;
describe User;&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we can use ORM to perform CRUD operations on our database. Let's update our route files to use prisma client to run operations.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`ts&lt;br&gt;
// user.route.ts&lt;/p&gt;

&lt;p&gt;import { PrismaClient } from '@prisma/client';&lt;br&gt;
const prisma = new PrismaClient();&lt;/p&gt;

&lt;p&gt;router.get('/', async (req: Request, res: Response) =&amp;gt; {&lt;br&gt;
    const users = await prisma.user.findMany();&lt;br&gt;
    res.send(users);&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;router.get('/:id', async (req: Request, res: Response) =&amp;gt; {&lt;br&gt;
    const user = await prisma.user.findUnique({&lt;br&gt;
        where: {&lt;br&gt;
            id: parseInt(req.params.id),&lt;br&gt;
        },&lt;br&gt;
    })&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;res.send(user);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;});&lt;/p&gt;

&lt;p&gt;router.post('/', async (req: Request, res: Response) =&amp;gt; {&lt;br&gt;
    const user = await prisma.user.create({&lt;br&gt;
        data: req.body&lt;br&gt;
    })&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;res.send(user);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;});&lt;/p&gt;

&lt;p&gt;router.delete('/:id', async (req: Request, res: Response) =&amp;gt; {&lt;br&gt;
    await prisma.user.delete({&lt;br&gt;
        where: {&lt;br&gt;
            id: parseInt(req.params.id),&lt;br&gt;
        },&lt;br&gt;
    })&lt;br&gt;
    res.send(&lt;code&gt;User with id: ${req.params.id} deleted&lt;/code&gt;);&lt;br&gt;
});&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`ts&lt;br&gt;
//blog.route.ts&lt;/p&gt;

&lt;p&gt;import { PrismaClient } from '@prisma/client';&lt;br&gt;
const prisma = new PrismaClient();&lt;/p&gt;

&lt;p&gt;router.get('/', async (req: Request, res: Response) =&amp;gt; {&lt;br&gt;
    const blogs = await prisma.blog.findMany();&lt;br&gt;
    res.send(blogs);&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;router.get('/:id', async (req: Request, res: Response) =&amp;gt; {&lt;br&gt;
    const blog = await prisma.blog.findUnique({&lt;br&gt;
        where: {&lt;br&gt;
            id: parseInt(req.params.id),&lt;br&gt;
        },&lt;br&gt;
    })&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;res.send(blog);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;});&lt;/p&gt;

&lt;p&gt;router.post('/', async (req: Request, res: Response) =&amp;gt; {&lt;br&gt;
    const createdBlog = await prisma.blog.create({ data: req.body });&lt;br&gt;
    res.send(createdBlog);&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;router.delete('/:id', async (req: Request, res: Response) =&amp;gt; {&lt;br&gt;
    await prisma.blog.delete({&lt;br&gt;
        where: {&lt;br&gt;
            id: parseInt(req.params.id),&lt;br&gt;
        },&lt;br&gt;
    })&lt;br&gt;
    res.send(&lt;code&gt;Blog with id: ${req.params.id} deleted&lt;/code&gt;);&lt;br&gt;
});&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, we can create user and their blog using your favorite tool like Postman.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`bash&lt;br&gt;
// First we create a dummy user&lt;br&gt;
curl --location 'localhost:3000/user' \&lt;br&gt;
--header 'Content-Type: application/json' \&lt;br&gt;
--data '{&lt;br&gt;
    "email": "&lt;a href="mailto:abc@test.com"&gt;abc@test.com&lt;/a&gt;"&lt;br&gt;
}'&lt;/p&gt;

&lt;p&gt;// Then blog from userId returned from previous command. In this case, authorId 1&lt;br&gt;
curl --location 'localhost:3000/blog' \&lt;br&gt;
--header 'Content-Type: application/json' \&lt;br&gt;
--data '{&lt;br&gt;
    "title": "Title",&lt;br&gt;
    "content": "Content",&lt;br&gt;
    "authorId": 1&lt;br&gt;
}'&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Link to commit for changes in this post &lt;a href="https://github.com/sumitbhanushali/bloggo/commit/a91c1424aa8a7279740338276af563bf1c0c5ee6" rel="noopener noreferrer"&gt;https://github.com/sumitbhanushali/bloggo/commit/a91c1424aa8a7279740338276af563bf1c0c5ee6&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Up Next
&lt;/h2&gt;

&lt;p&gt;This is where our Part 1 ends. We have learnt about VCS like git that how it can make a developer's life a lot simpler, about dependency declaration manifest that how it can make setting up project smoother, about storing config in env vars which makes deployment secure and benefits of using backing services as pluggable resources.&lt;br&gt;
On next part we will continue with next 4 steps i.e 5. Build, Setup and Run, 6. Processes, 7. Port Binding, 8. Concurrency according to 12 Factor App's methodology&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>node</category>
      <category>express</category>
    </item>
    <item>
      <title>12 Factor App in NodeJS Part 0: Intro</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Thu, 30 Nov 2023 09:18:34 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/12-factor-app-in-nodejs-part-0-intro-m0a</link>
      <guid>https://forem.com/sumitbhanushali/12-factor-app-in-nodejs-part-0-intro-m0a</guid>
      <description>&lt;p&gt;We have all heard that attachments are bad, well this applies to software development too. Your app maybe too dependent on OS or Cloud Provider. Your libraries might only work on specific OS or your app must be too much dependent on cloud sdks. Some OS are better suited in certain tasks than other and a policy change in some cloud provider can lead to huge expenses.&lt;/p&gt;

&lt;p&gt;This leads to huge obstacle when you need to scale your app and can lead to huge expenses since moving out of particular cloud or OS is a herculean task. Your App should be flexible enough to make sure you dodge such bullets easily deployments must be as smooth as possible to be able to ship more features faster and without any bugs with minimal intervention of any human resource.&lt;/p&gt;

&lt;p&gt;App must be able to scale automatically up or down on demand which leads to savings on cloud bills on non active hours and better User experience by delivering faster responses at peak times.&lt;/p&gt;

&lt;p&gt;That’s why engineers from heroku came up with 12 Factor app methodology which applies to web apps in general. These methodologies when applied will help scale your app easily, make your app platform agnostic and make deployments smoother by maintaining proper build, test and deploy stages and keeping minimal difference between dev and prod environment. You can easily deploy your apps on aws, azure, gcp, heroku or even on on-premise servers&lt;/p&gt;

&lt;p&gt;As mentioned in the name 12 Factor app is a list of 12 factors, I will list them here briefly and will write a detailed post with code implementation in NodeJS; ExpressJS + TS to be specific in later posts&lt;/p&gt;

&lt;h3&gt;
  
  
  I. Codebase
&lt;/h3&gt;

&lt;p&gt;Track your codebase in revision control system such as git. Why? It helps maintaining multiple versions of an app in single codebase&lt;/p&gt;

&lt;h3&gt;
  
  
  II. Dependencies
&lt;/h3&gt;

&lt;p&gt;Language runtime and its Package manager should be the only prerequisite to run the app. Other dependencies should be declared explicitly in a dependency declaration manifest file and should be isolated i.e no global packages can be used inside the app. This results in deterministic builds and thus makes it extremely simple to setup dev and prod environments&lt;/p&gt;

&lt;h3&gt;
  
  
  III. Config
&lt;/h3&gt;

&lt;p&gt;An app’s config is everything that is likely to vary between deploys (staging, production, developer environments, etc) which are credentials to external services such as Database(MySQL, Redis), Cloud Providers or External APIs like twitter, dropbox, etc. Such configs should be stored in environment variables. This prevents accidental leaking of sensitive information and reduces hassle of updating such configs by just updating environment variables instead of manually editing file on server&lt;/p&gt;

&lt;h3&gt;
  
  
  IV. Backing Services
&lt;/h3&gt;

&lt;p&gt;A backing service is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as MySQL or MongoDB), messaging/queueing systems (such as RabbitMQ or Kafka), caching systems (such as Redis). App should be able to swap out a local MySQL database with one managed by a third party (such as Amazon RDS) without any changes to the app’s code. This makes app reliable and more easy to scale since Resources can be easily attached to and detached from deploys at will. For example, if the app’s database is misbehaving due to a hardware issue, the app’s administrator might spin up a new database server restored from a recent backup. The current production database could be detached, and the new database attached — all without any code changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  V. Build, Release, Run
&lt;/h3&gt;

&lt;p&gt;Build Stage is when we are done with developing code and are confident for deploy. We thus run a build command which outputs an executable file which cannot be modified by us.&lt;/p&gt;

&lt;p&gt;Release Stage is where we combine our build with config which makes app able to run. This releases should be tagged with unique ReleaseID.&lt;/p&gt;

&lt;p&gt;Run Stage is where we run our release and make our app accessible to outside world.&lt;/p&gt;

&lt;p&gt;This stages should be strictly seperate and any change in code should trigger new build, release and run stage. Run stage should be as simple as possible, process or system restarts can easily rerun our run stage without requiring manual intervention. This also simplifies rolling back to previous release when required&lt;/p&gt;

&lt;h3&gt;
  
  
  VI. Processes
&lt;/h3&gt;

&lt;p&gt;Our App runs on processes. It can be single process on developer’s machine or multiple processes on production. This processes must be stateless, all states should be stored in a storage solution. Temporary state can be stored in caching solution like redis and permanent state in Database like mysql. App should be able to handle process or system restarts and recover to right state. Also, since our app is running on multiple processes, same user can be routed to different process and its state information becomes inaccessible. Making our processes stateless makes our app reliable and ready to scale&lt;/p&gt;

&lt;h3&gt;
  
  
  VII. Port binding
&lt;/h3&gt;

&lt;p&gt;Your service must be self contained and be able to bind to a port to serve requests without relying on other software such as nginx to create a web-facing service. This must happen entirely in user space, that is, within the app’s code. [why]&lt;/p&gt;

&lt;h3&gt;
  
  
  VIII. Concurrency
&lt;/h3&gt;

&lt;p&gt;In the twelve-factor app, processes are a first class citizen. Using this model, the developer can architect their app to handle diverse workloads by assigning each type of work to a process type. For example, HTTP requests may be handled by a web process, and long-running background tasks handled by a worker process. Since our apps are already running on stateless processes, fearless concurrency is easily achieved and our app can scale without making any changes to code&lt;/p&gt;

&lt;h3&gt;
  
  
  IX. Disposability
&lt;/h3&gt;

&lt;p&gt;Stateless processes are disposable, meaning they can be started or stopped at a moment’s notice. This facilitates fast elastic scaling and makes zero downtime deployments possible. Our app should take minimal time to startup and shutdown gracefully. Our app should also be prepared for sudden death. All these makes sure our app is reliable, easy to deploy and scale elastically&lt;/p&gt;

&lt;h3&gt;
  
  
  X. Dev/Prod Parity
&lt;/h3&gt;

&lt;p&gt;To prevent “This works on my machine”. This happens because developers by using adapter solution use lightweight solution on development machine and different solution on prod. Some inconsistencies between these two can cause production to break which makes our app unreliable and thus damaging business&lt;/p&gt;

&lt;h3&gt;
  
  
  XI. Logs
&lt;/h3&gt;

&lt;p&gt;Our app should not worry about routing or storage of its output stream. It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to stdout. It will be responsibility of execution environment on how it should handle stdout. In case when dev is developing on hist local machine, the developer will view this stream in the foreground of their terminal.&lt;/p&gt;

&lt;p&gt;In staging or production deploys, each process stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival.&lt;/p&gt;

&lt;h3&gt;
  
  
  XII. Admin Processes
&lt;/h3&gt;

&lt;p&gt;Admin processes such as running database migration or running some script to debug should be run in an environment that is identical to target environment. Twelve-factor strongly favors languages which provide a REPL shell out of the box, and which make it easy to run one-off scripts. In a local deploy, developers invoke one-off admin processes by a direct shell command inside the app’s checkout directory. In a production deploy, developers can use ssh or other remote command execution mechanism provided by that deploy’s execution environment to run such a process.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>architecture</category>
      <category>node</category>
    </item>
    <item>
      <title>Benefits of using Typescript with ExpressJS with Project Template</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Sat, 25 Nov 2023 14:39:10 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/setup-crud-app-express-typescript-and-mysql-2knh</link>
      <guid>https://forem.com/sumitbhanushali/setup-crud-app-express-typescript-and-mysql-2knh</guid>
      <description>&lt;p&gt;In this post, we will setup our Backend service. We will be using ExpressJS for APIs, MySQL for storage and Prisma for ORM. We will be using Typescript as primary language. We will be using Docker to host MySQL on our machine. This will only work on Node Version: v20.10.0 and above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Typescript?
&lt;/h2&gt;

&lt;p&gt;TypeScript enhances Express.js web development by introducing static typing, catching potential bugs early and improving code maintainability. With superior IDE support and modern JavaScript features, TypeScript offers a productive development experience.TypeScript with Express.js combines the simplicity of Express.js with TypeScript's static typing benefits, resulting in more reliable and maintainable web applications.&lt;/p&gt;

&lt;p&gt;Our project will be simple blog application named bloggo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;bloggo &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;bloggo &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;touch &lt;/span&gt;README.md &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"# Bloggo &lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Simple Blog Application"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; README.md

npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To Add Typescript support&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-D&lt;/span&gt; typescript @types/node ts-node

npx tsc &lt;span class="nt"&gt;--init&lt;/span&gt; &lt;span class="nt"&gt;--rootDir&lt;/span&gt; ./ &lt;span class="nt"&gt;--outDir&lt;/span&gt; .dist &lt;span class="nt"&gt;--target&lt;/span&gt; es2020 &lt;span class="nt"&gt;--allowJs&lt;/span&gt; &lt;span class="nt"&gt;--noImplicitAny&lt;/span&gt; &lt;span class="nb"&gt;false

&lt;/span&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; nodemon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have installed 3 packages as dev dependencies, their functionality is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;typescript:&lt;/strong&gt; this package is required to transpile ts to js &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;@types/node:&lt;/strong&gt; this provides type definitions like Request, Response for NodeJS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ts-node:&lt;/strong&gt; this is combination of two package ts transpiles given ts files to js files and node executes those js files&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;we use tsc package to generate tsconfig.json for us. We need tsconfig.json file to instruct how to handle our ts files&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;--rootDir:&lt;/strong&gt; location to all ts files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--outDir:&lt;/strong&gt; location to place transpiled js files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--target:&lt;/strong&gt; javascript version for js files to be generated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--allowJs:&lt;/strong&gt; whether it should also allow js files, if disabled it will only allow ts files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--noImplicitAny:&lt;/strong&gt; if true, will not allow any types to have ambigious 'any' declaration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;nodemon will be used to watch our files and refresh automatically when any changes detected.&lt;/p&gt;

&lt;p&gt;Next, we will install express and @types/express for building APIs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i express
npm i &lt;span class="nt"&gt;-D&lt;/span&gt; @types/express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a basic server which will just respond with Hello World on port 3000&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//index.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`listening on &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will run this using nodemon we had previously installed, we will add some npm scripts in package.json to simplify our efforts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;elided&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start:dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nodemon --exec node -r ts-node/register --env-file=config.env index.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:watch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc --watch"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;elided&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;- start:dev:&lt;/strong&gt; we need to use ts-node we had installed previously to run ts files without rebuilding for every change done while development. Since ts-node does not directly support --env-file yet, we are using -r to require (import) ts-node/register&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;build:&lt;/strong&gt; tsc which is part of typescript package will transpile our ts into js and place it in .dist folder as mentioned in tsconfig.json file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;build⌚&lt;/strong&gt; This will run build in watch mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On running &lt;code&gt;npm run start:dev&lt;/code&gt; on terminal, our app will start running on port 3000. When you will navigate to &lt;code&gt;localhost:3000&lt;/code&gt; you will receive &lt;code&gt;hello world&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, we will add some routes for interacting with &lt;code&gt;blog&lt;/code&gt; and &lt;code&gt;user&lt;/code&gt; resource. Create a folder named routes and add two files named &lt;code&gt;blog.router.ts&lt;/code&gt; and &lt;code&gt;user.router.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// blog.router.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;List of blogs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Blog: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Blog created`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Blog with id: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; deleted`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//user.router.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;List of users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`User: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`User created`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`User with id: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; deleted`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import these routes in our main index.ts file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//index.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;blogRouter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./routes/blog.route&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;userRouter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./routes/user.route&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;blogRouter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userRouter&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 now access respective routes at &lt;code&gt;/blog/&lt;/code&gt; and &lt;code&gt;/user/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next We need to add Database for storing our data. We will use image of MySQL from docker hub and prisma for ORM for performing CRUD operations on MySQL. &lt;br&gt;
We will start with prisma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;prisma &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
npx prisma init &lt;span class="nt"&gt;--datasource-provider&lt;/span&gt; mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate prisma folder in our root directory where in schema.prisma will contain database connection details and prisma models which will be used to create/update tables in our database. We will add two models in schema.prisma&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;        &lt;span class="nx"&gt;Int&lt;/span&gt;      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;autoincrement&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;     &lt;span class="nb"&gt;String&lt;/span&gt;   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;unique&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;      &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
  &lt;span class="nx"&gt;blogs&lt;/span&gt;     &lt;span class="nx"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="nx"&gt;createdAt&lt;/span&gt; &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;updatedAt&lt;/span&gt; &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;updatedAt&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="nx"&gt;Blog&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;        &lt;span class="nx"&gt;Int&lt;/span&gt;      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;autoincrement&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;     &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;   &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
  &lt;span class="nx"&gt;published&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;author&lt;/span&gt;    &lt;span class="nx"&gt;User&lt;/span&gt;     &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;relation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;authorId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;references&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="nx"&gt;authorId&lt;/span&gt;  &lt;span class="nx"&gt;Int&lt;/span&gt;
  &lt;span class="nx"&gt;createdAt&lt;/span&gt; &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;updatedAt&lt;/span&gt; &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;updatedAt&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This model files are self-explanatory. You can check more about prisma model here: &lt;a href="https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference" rel="noopener noreferrer"&gt;https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference&lt;/a&gt;&lt;br&gt;
Next step is to execute prisma script to run migration which will create these model files inside our database. But before this we need to setup our mysql instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull mysql

docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; mysqldb &lt;span class="nt"&gt;-p&lt;/span&gt; 3306:3306 &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;password &lt;span class="nt"&gt;-d&lt;/span&gt; mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will pull mysql image from docker hub and create container from it, we have set container name as &lt;code&gt;mysqldb&lt;/code&gt; and root password as &lt;code&gt;password&lt;/code&gt;. Our db will listen on port 3306&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; mysqldb sh

mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; 
// enter &lt;span class="s2"&gt;"password"&lt;/span&gt; when prompted

create database bloggo&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way we can attach to our db container and execute our bash command to connect to mysql and create database named "bloggo". type &lt;code&gt;exit&lt;/code&gt; to exit from mysql and container respectively&lt;br&gt;
We will update our environment variable to our credentials in config.env file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DATABASE_URL="mysql://root:password@localhost:3306/bloggo"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we will execute prisma script to run migrations, this command also generates prisma client files which comes in handy when using ORM&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx prisma migrate dev &lt;span class="nt"&gt;--name&lt;/span&gt; init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now check that tables have been connected by connecting to mysql instance. Run this commands after connecting to mysql instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;use bloggo&lt;span class="p"&gt;;&lt;/span&gt;
show tables&lt;span class="p"&gt;;&lt;/span&gt;

describe Blog&lt;span class="p"&gt;;&lt;/span&gt;
describe User&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can use ORM to perform CRUD operations on our database. Let's update our route files to use prisma client to run operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// user.route.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PrismaClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@prisma/client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PrismaClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`User with id: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; deleted`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//blog.route.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PrismaClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@prisma/client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PrismaClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blogs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createdBlog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createdBlog&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Blog with id: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; deleted`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can create user and their blog using your favorite tool like Postman.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// First we create a dummy user
curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s1"&gt;'localhost:3000/user'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
    "email": "abc@test.com"
}'&lt;/span&gt;

// Then blog from userId returned from previous command. In this &lt;span class="k"&gt;case&lt;/span&gt;, authorId 1
curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s1"&gt;'localhost:3000/blog'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
    "title": "Title",
    "content": "Content",
    "authorId": 1
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This finishes up our setup of CRUD app. We started by first creating an empty directory for our blog application and initializing it with npm to setup package.json. We added typescript support by installing few packages and generating tsconfig.json. We added few CRUD apis for Blog and User. We then added Prisma for ORM and created instance for MySQL, connected the two, ran migrations and in the end we got full functioning CRUD app.&lt;br&gt;
This app is far from production like we don't have auth, request body validations, pagination, docker setup for our api and many other things. These things will be covered in later post. &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>node</category>
      <category>express</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What Would Life Without Git Be Like</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Wed, 22 Nov 2023 07:41:49 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/what-would-life-without-git-be-like-66a</link>
      <guid>https://forem.com/sumitbhanushali/what-would-life-without-git-be-like-66a</guid>
      <description>&lt;p&gt;Nowadays, everyone is familiar with version control system aka VCS, such as Git, Mercurial, or Subversion, Git being the most popular one. It has become second nature to us that the first thing we do after initializing our project is run &lt;code&gt;git init &amp;amp;&amp;amp; git add . &amp;amp;&amp;amp; git commit -m "initial commit"&lt;/code&gt;. To understand how important VCS is let's assume we don't know about VCS or something like VCS doesn't even exist.&lt;/p&gt;

&lt;p&gt;Let's take 4 scenarios to understand how difficulty escalates exponentially&lt;br&gt;
1) Working Solo on a Project with Single Deployment&lt;br&gt;
2) Working Solo on a Project with Multiple Versions and Deployments&lt;br&gt;
3) Working in a Team of 4 with Single Version and Deployment&lt;br&gt;
4) Working in a Team of 4 with Multiple Versions and Deployments&lt;/p&gt;

&lt;p&gt;Here, deployment means version of codebase. Single Deployment means only one version of codebase that will be deployed. Multiple Deployments means multiple versions(including client specific) of codebase in multiple environments(staging, uat, production)&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 1: Working Solo on a Project with Single Deployment
&lt;/h3&gt;

&lt;p&gt;As a solo developer without version control, working on a project with a single deployment becomes a risky situation. Any code changes made are irreversible, and there's no safety net in case of errors. If a bug is introduced, there's no straightforward way to revert to a previous, stable state. The lack of versioning makes it challenging to track changes over time, and it's easy to lose sight of the project's evolution.&lt;/p&gt;

&lt;p&gt;Collaboration with past iterations is impossible, making it difficult to understand the reasoning behind certain decisions or to revisit successful implementations. The absence of branching and merging capabilities means that experimenting with new features or fixes could disrupt the entire codebase.&lt;/p&gt;

&lt;p&gt;Deployments are a nerve-wracking process. If an issue arises during deployment, rolling back to a working state is a manual and error-prone task. Without a VCS, there's no efficient means of documenting the deployed versions or managing configurations for different environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 2: Working Solo on a Project with Multiple Versions and Deployments
&lt;/h3&gt;

&lt;p&gt;In this scenario, the absence of version control worsens the challenges faced in the first scenario. Managing multiple versions and deployments without VCS becomes a logistical nightmare. Keeping track of different code states for various features or environments is practically impossible.&lt;/p&gt;

&lt;p&gt;Each deployment is a high-stakes endeavor, as there is no systematic way to isolate changes specific to a version or deployment. Debugging becomes a herculean task, and the risk of introducing new bugs while fixing existing issues looms large. Without branching, trying out experimental features or implementing temporary fixes without affecting the main codebase becomes nearly impossible.&lt;/p&gt;

&lt;p&gt;Documentation is limited to external notes or comments within the code, making it hard to understand the rationale behind specific versions or deployments. Coordinating changes across different branches or versions requires meticulous manual effort, leading to a high probability of errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 3: Working in a Team of 4 with Single Version and Deployment
&lt;/h3&gt;

&lt;p&gt;Without version control in a team setting, collaboration turns chaotic. Coordinating efforts among team members becomes a communication-heavy process, relying on constant updates and manual file sharing. The risk of overwriting each other's work is ever-present, and resolving conflicts is an arduous manual task.&lt;/p&gt;

&lt;p&gt;There's no clear history of changes, making it difficult to attribute modifications to specific team members, there will be blame games of faulty code as we won't be able to pinpoint who introduced the faulty code. Debugging and troubleshooting are cumbersome, as there's no easy way to identify when and why a particular change was made.&lt;/p&gt;

&lt;p&gt;Deployment is a risky and unpredictable process, with no efficient rollback mechanism. Coordinating releases requires meticulous planning and synchronization among team members, increasing the likelihood of errors and downtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 4: Working in a Team of 4 with Multiple Versions and Deployments
&lt;/h3&gt;

&lt;p&gt;In a team setting with multiple versions and deployments but without version control, the challenges escalate exponentially. Collaboration becomes a logistical nightmare, with each team member potentially working on a different version or deployment. Coordinating changes and ensuring a cohesive codebase is a constant struggle.&lt;/p&gt;

&lt;p&gt;Without branching and merging capabilities, integrating features or fixes from different team members becomes an error-prone process. The risk of introducing conflicts and breaking the codebase during integration is high. Keeping track of changes across multiple branches or versions requires meticulous manual effort and is prone to oversight.&lt;/p&gt;

&lt;p&gt;Deployments are high-stakes events, and rolling back to a stable state in case of issues is a manual and time-consuming task. The lack of versioning makes it challenging to manage configurations for different environments, leading to potential deployment errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  It was just a Nightmare
&lt;/h2&gt;

&lt;p&gt;To sum it up, without version control, it's like navigating a coding maze with a blindfold. Adding a version control system is like turning on the lights — suddenly, everything just clicks. I hope after reading this, your appreciation for VCS increases tenfold&lt;/p&gt;

</description>
      <category>git</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>github</category>
    </item>
    <item>
      <title>REST API Best Practices: Design &amp; Security</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Tue, 21 Nov 2023 06:27:58 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/rest-api-best-practices-design-security-4bi</link>
      <guid>https://forem.com/sumitbhanushali/rest-api-best-practices-design-security-4bi</guid>
      <description>&lt;h2&gt;
  
  
  REST in Brief
&lt;/h2&gt;

&lt;p&gt;A RESTful (Representational State Transfer) API (Application Programming Interface) is an interface that allows systems to communicate with each other over the internet. REST is often used in the context of web services and APIs to enable the communication and exchange of data between systems.&lt;/p&gt;

&lt;p&gt;REST API gives freedom to design API however you want but for building secure, scalable, reliable and maintainable backend system it is important to follow conventions accross backend system. Here are some of those Best Practices which can help you achieve that &lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Resource Names
&lt;/h3&gt;

&lt;p&gt;Resource name is typically name of the model/table in a database, it can also represent some virtual logical entity. Using Resource name makes the API more human readable and understandable and it makes it clear what the API endpoint represents.&lt;br&gt;
Also including resource names in the URL allows for a hierarchical structure that reflects the relationships between resources. For example, /users/123/orders indicates a user with ID 123 and their associated orders.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /querycarts/123 -&amp;gt; GET /carts/123&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  use plurals
&lt;/h3&gt;

&lt;p&gt;Pluralization is a natural part of human language. When dealing with multiple instances of a resource, using the plural form in the URL can make the API more intuitive and easier to understand. It aligns with how we typically describe multiple instances of a noun in English. Using plurals helps distinguish between individual resource instances and collections of resources. For example, &lt;code&gt;/user/123&lt;/code&gt; might represent a single user, while &lt;code&gt;/users&lt;/code&gt; represents the entire collection of users.&lt;/p&gt;

&lt;p&gt;HTTP methods like GET, POST, PUT, and DELETE are often used with plural resource names. For example, a GET request to &lt;code&gt;/users&lt;/code&gt; might retrieve a list of users, and a POST request to &lt;code&gt;/users&lt;/code&gt; might create a new user. This aligns with the convention of using plurals for resource names. In many cases, RESTful APIs are built on top of databases, where tables are often named in the plural form to represent collections of entities. Aligning resource names with database table names can simplify the mapping between the API and the underlying data structure.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /cart/123 -&amp;gt; GET /carts/123&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Idempotency
&lt;/h3&gt;

&lt;p&gt;Idempotence ensures that the same operation can be repeated multiple times without causing different outcomes. &lt;/p&gt;

&lt;p&gt;In unreliable networks, requests may fail or be sent multiple times. Idempotence ensures that if a request is duplicated due to network issues or client retries, the system's state remains consistent.&lt;br&gt;
It allows clients to implement a safe retry mechanism. If a request fails, the client can simply retry it without the fear of causing unintended changes or inconsistencies in the system.&lt;br&gt;
In distributed systems where multiple components may process a request, idempotence helps maintain consistency. Even if a request is processed by multiple nodes, the end result should be the same as if it were processed only once.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;POST /carts -&amp;gt; POST /carts {requestId: 123}&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Versioning
&lt;/h3&gt;

&lt;p&gt;API versioning allows developers to introduce changes, improvements, or new features to an API without breaking existing clients. By maintaining backward compatibility, existing applications can continue to function as expected even as the API evolves.&lt;br&gt;
Versioning provides a way for clients to transition from one version of the API to another at their own pace. Clients can choose to adopt a new API version when they are ready, reducing the risk of disruptions to their services.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /carts/123 -&amp;gt; GET /v1/carts/123&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Query After Soft Deletion
&lt;/h3&gt;

&lt;p&gt;Soft deletion typically involves marking entries as deleted instead of physically removing them from the system&lt;br&gt;
By default, the API should exclude soft-deleted entries from the response. This ensures that clients not explicitly requesting deleted entries receive the expected behavior.&lt;br&gt;
Introduce a query parameter or filter to allow clients to specify whether they want to include soft-deleted entries in the response.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /carts -&amp;gt; GET /carts?includeDeleted=true&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pagination
&lt;/h3&gt;

&lt;p&gt;Pagination is a technique used in web development and APIs to break down large sets of data into smaller, more manageable chunks or pages. Loading and displaying a large dataset all at once can lead to slow response times and increased server and network loads. Pagination allows you to retrieve and display smaller subsets of data, improving overall performance and user experience.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /carts -&amp;gt; GET /carts?pageSize=xx&amp;amp;pageToken=xx&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sorting
&lt;/h3&gt;

&lt;p&gt;When presenting data to users in a user interface, it's often helpful to allow them to choose how the data is sorted. For example, in an e-commerce application, users might want to sort products by price, name, or popularity.&lt;br&gt;
In scenarios where the API is used for reporting or data analysis, clients may want to retrieve data in a specific order to facilitate easier analysis. For example, sorting by timestamp for time-series data or sorting by a numeric field for ranking purposes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /carts -&amp;gt; GET /carts?sortyBy=time&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Filtering
&lt;/h3&gt;

&lt;p&gt;Filters are often used to implement search functionality within an API. Clients can specify search criteria to retrieve only the resources that match the specified conditions. For example, &lt;code&gt;/users?filter=name:John&lt;/code&gt; might return a list of users with the name "John."&lt;/p&gt;

&lt;p&gt;Clients may need to filter data based on specific attributes or fields. For instance, in an e-commerce API, clients might want to retrieve products within a certain price range, such as &lt;code&gt;/products?filter=price:10-50&lt;/code&gt; to get products with prices between $10 and $50.&lt;/p&gt;

&lt;p&gt;Filters enable conditional retrieval of resources. Clients can request resources that satisfy a particular condition, allowing them to fetch data based on dynamic criteria.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /carts -&amp;gt; GET /carts?filter=color:red&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure Access
&lt;/h3&gt;

&lt;p&gt;The X-API-KEY header is often used for API key-based authentication. Each client is issued a unique API key, and the server validates incoming requests by checking the presence and correctness of the API key. This helps control access to the API and ensures that only authorized clients can make requests.&lt;/p&gt;

&lt;p&gt;The X-EXPIRY header is used to specify the expiration time of a request. It helps prevent replay attacks by indicating that a request is only valid for a certain period. Servers can check the timestamp in the X-EXPIRY header and reject requests that have expired, enhancing the security of the API.&lt;/p&gt;

&lt;p&gt;The X-SIGNATURE header is used to include a cryptographic signature or hash of the request data. This signature is generated using a secret key known only to the server and the client. The server can verify the integrity and authenticity of the request by recalculating the signature on its end and comparing it with the provided X-SIGNATURE. This helps ensure that the request has not been tampered with during transit.&lt;/p&gt;

&lt;p&gt;Together, these headers contribute to establishing a secure communication channel between clients and servers, which is crucial when dealing with sensitive or private data.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;X-API-KEY=xxx -&amp;gt; X-API-KEY=xxx  X-EXPIRY=xxx  X-REQUEST_SIGNATURE=xxx(hmac(URL + Query + Expiry + Body))&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Nested Resources For Accessing Cross Reference Resource
&lt;/h3&gt;

&lt;p&gt;Nested resources can represent a logical hierarchy, making the structure of the API more intuitive. This is particularly useful when there is a clear parent-child relationship between resources. For example, /orders/123/items signifies that you are retrieving items belonging to the order with ID 123.&lt;/p&gt;

&lt;p&gt;The use of nested resources provides context and identification for the relationships between entities. When you see a nested resource like /users/456/posts, it's clear that you are retrieving posts associated with the user with ID 456.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /carts/123?item=321 -&amp;gt; GET /carts/123/items/321&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  POST: Use Request Body Instead Of Query Params
&lt;/h3&gt;

&lt;p&gt;Query parameters are typically appended to the URL and are limited in terms of length. Sending data in the request body allows for larger and more complex data payloads. This is important when dealing with substantial amounts of data or when the data structure is hierarchical.&lt;br&gt;
Placing sensitive information, such as passwords or user credentials, in the request body provides a more secure approach compared to query parameters. Query parameters are visible in the URL, which may expose sensitive information in logs, browser history, or other places.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;POST /carts/123?addItem=321 -&amp;gt; POST /carts/123/items:add {itemId: 123}&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rate Limit
&lt;/h3&gt;

&lt;p&gt;Rate limiting helps protect an API against abuse, misuse, or malicious attacks. By restricting the number of requests a client can make, it mitigates the risk of denial-of-service (DoS) attacks, brute-force attacks, and other forms of abuse that could overwhelm the API servers.&lt;br&gt;
It promotes fair usage of API resources by preventing any single client from monopolizing server resources. This ensures that resources are distributed more equitably among all clients,preventing one client from negatively impacting the experience of others.&lt;/p&gt;

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

&lt;p&gt;It's essential to note that these are conventions. The key is to choose a convention and stick to it consistently throughout your API. Whichever approach you choose, clarity, consistency, and adherence to RESTful principles should be the guiding principles in your API design. Additionally, documenting your API well helps developers understand the naming conventions you've chosen. preventing one client from negatively impacting the experience of others.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>api</category>
      <category>restapi</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Microservices: Why You Need To Use npm Workspaces</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Fri, 06 Oct 2023 17:24:47 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/microservices-why-you-need-to-use-npm-workspaces-3095</link>
      <guid>https://forem.com/sumitbhanushali/microservices-why-you-need-to-use-npm-workspaces-3095</guid>
      <description>&lt;p&gt;If you are using microservice architecture to organize your project, you most likely will be having common helper functions which are copied across all microservices. Helper functions likes date utils, error handlers, customized loggers, response normalization, etc. This leads to code duplication. Maintaining, testing and versioning such codebase becomes a nightmare if not handled well &lt;/p&gt;

&lt;p&gt;This problem is typically solved by either using &lt;code&gt;npm link&lt;/code&gt; or by publishing private packages on Package Managers like npm.&lt;/p&gt;

&lt;p&gt;1) &lt;code&gt;npm link&lt;/code&gt; works by creating symbolic links between packages. This can cause issues with certain project setups or operating systems. Also, these are more cumbersome to setup and maintain&lt;/p&gt;

&lt;p&gt;2) Publishing to, and maintaining, a private package repository requires additional overhead – both in terms of time (publishing, updating) and infrastructure (maintaining the repository, ensuring its security, backup, etc.). Handling authentication, permissions, and access for a private npm registry can introduce complexities. Maintaining a private package repository might involve costs – both in terms of infrastructure and potential licensing fees, depending on the solution.&lt;/p&gt;

&lt;p&gt;All such issues and more are solved efficiently by npm workspace&lt;/p&gt;

&lt;h3&gt;
  
  
  npm Workspaces
&lt;/h3&gt;

&lt;p&gt;npm workspace is a feature introduced in npm v7 that allows for managing multiple packages within a single top-level, root package. It enables you to work on interdependent packages as a single unit, making it easier to develop and test them together. This can be particularly useful in monorepo setups or projects with complex dependency structures.&lt;/p&gt;

&lt;p&gt;With npm workspace, you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Manage Interdependent Packages&lt;/strong&gt;: npm workspace allows you to work on multiple packages simultaneously, making it easier to develop and test them together. For example, you can make changes to a shared library used by multiple projects and test those changes in the context of each project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share Dependencies&lt;/strong&gt;: npm workspace enables you to share dependencies between packages. This means that if multiple packages in your project require the same dependency, you can install it once at the workspace level and have it shared across all packages. This helps to optimize disk space and simplify dependency management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run Commands Across Packages&lt;/strong&gt;: npm workspace allows you to run commands across all packages in your project. For instance, you can run a build command or a test command that will be executed in each package, ensuring consistency and efficiency in your project's development process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manage Versioning&lt;/strong&gt;: npm workspace provides a unified versioning approach for packages within the workspace. You can easily update versions for all packages at once, ensuring compatibility and consistency across the project.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are just a few examples of what can be done with npm workspace. It provides a powerful toolset for managing multiple packages within a project, promoting collaboration, modularity, and efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Walkthrough:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Setup Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir&lt;/code&gt; or &lt;code&gt;cd&lt;/code&gt; into your project&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;test-project&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;test-project&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;npm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;init&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-y&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Parent Workspace Configuration (root package.json)&lt;/strong&gt;:&lt;br&gt;
Add &lt;code&gt;workspaces&lt;/code&gt; key which will be array of packages. This is the configuration that you'll set up at the root of your workspace to include both of the packages.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"test-project"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workspaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"libraries/*"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"install"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm install --ignore-scripts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run test:libraries"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test:libraries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run test --workspaces"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;"workspaces"&lt;/code&gt; field specifies the directory pattern for the packages within the workspace. In this case, it is set to &lt;code&gt;"packages/*"&lt;/code&gt;, which means that all packages within the &lt;code&gt;packages&lt;/code&gt; directory will be part of the workspace.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;"scripts"&lt;/code&gt; section includes two example scripts. The &lt;code&gt;"install"&lt;/code&gt; script is used to install dependencies across all packages in the workspace, while ignoring any individual package scripts. The &lt;code&gt;"test:packages"&lt;/code&gt; script is used to run tests in each package within the workspace. The &lt;code&gt;--workspaces&lt;/code&gt; flag is added to the &lt;code&gt;"test"&lt;/code&gt; script to ensure that the test command is executed in each package.&lt;/p&gt;

&lt;p&gt;The directory structure will look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/test-project
|-- /libraries
|   |-- /package-a
|   |-- /package-b
|-- package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Package A&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//file:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/libraries/package-a/package.json&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"package-a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: run tests from root&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//file: /libraries/package-a/index.js&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from Package A!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Package B&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//file:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/packages/package-b/package.json&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"package-b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"package-a"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: run tests from root&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//file: /packages/package-b/index.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;packageA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;package-a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;packageA&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from Package B!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;With the above setup, &lt;strong&gt;&lt;code&gt;package-b&lt;/code&gt;&lt;/strong&gt; depends on &lt;strong&gt;&lt;code&gt;package-a&lt;/code&gt;&lt;/strong&gt;. When using npm workspaces, you can use local versions of your packages within the workspace without having to publish them to npm.&lt;/p&gt;

&lt;p&gt;After creating this structure, you can run &lt;strong&gt;&lt;code&gt;npm install&lt;/code&gt;&lt;/strong&gt; in the root directory, and npm will install all the dependencies for all packages, linking them where appropriate.&lt;/p&gt;

&lt;p&gt;Remember that the actual code in each package is minimal for illustration purposes, and you can extend them as needed for your projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Helpful Commands for Reference:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Installing Workspace Dependencies&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;This will install dependencies for all the packages defined in your workspace configuration.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Running Scripts Across Workspaces&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;If you want to run a specific script defined in a &lt;code&gt;package.json&lt;/code&gt; script section of one of your workspaces, you can use the &lt;code&gt;-w&lt;/code&gt; or &lt;code&gt;--workspace&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;For instance, to run the test script for a workspace named &lt;code&gt;package-a&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run test -w package-a
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;To run the test script for all workspaces:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run test --workspaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Listing Dependencies Across Workspaces&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;You can list dependencies across all workspaces using the &lt;code&gt;ls&lt;/code&gt; or &lt;code&gt;list&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm ls
&lt;/code&gt;&lt;/pre&gt;

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

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;br&gt;
npm workspaces are designed to make managing monorepos easier. This means that while you can manage dependencies, scripts, and other tasks at the individual workspace level, it's often beneficial to handle shared tasks at the root level to maintain consistency and simplicity.&lt;/p&gt;

</description>
      <category>node</category>
      <category>npm</category>
      <category>microservices</category>
      <category>javascript</category>
    </item>
    <item>
      <title>3 Beginner Level Quirky Leetcode Problems That Made Me Go WOW!!</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Sun, 03 Sep 2023 06:53:06 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/3-beginner-level-quirky-leetcode-problems-that-made-me-go-wow-3cfl</link>
      <guid>https://forem.com/sumitbhanushali/3-beginner-level-quirky-leetcode-problems-that-made-me-go-wow-3cfl</guid>
      <description>&lt;p&gt;&lt;a href="https://leetcode.com/problems/valid-anagram/"&gt;242. Valid Anagram&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Demonstrates how we can leverage limited set of inputs and mapping technique to save on both space and time&lt;/p&gt;

&lt;p&gt;Solution&lt;/p&gt;

&lt;p&gt;We can solve this problem by using a array of size 26(alphabet size) with counts 0. We can traverse the first string s, find exact index in array of each char using (charCode - 97) and store the frequency of each character in a array. Then we can traverse the second string t and decrement the frequency of each character in the array. If the array contains only 0 values at the end, then the second string t is an anagram of the first string s.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;isAnagram&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// If the lengths are different, then t cannot be an anagram of s&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Initialize a array with 0 frequencies for each character&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;freqTable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Traverse the first string s and update the frequency table&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;freqTable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;charCode&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="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Traverse the second string t and decrement the frequency table&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;freqTable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;charCode&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;freqTable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;charCode&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// If the frequency goes below 0, then t cannot be an anagram of s&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// If all frequencies are 0, then t is an anagram of s&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isAnagram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anagram&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nagaram&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;   &lt;span class="c1"&gt;// Output: true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isAnagram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;car&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;   &lt;span class="c1"&gt;// Output: false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Time Complexity: O(n) where n is the length of the strings s and t. We traverse each string only once.&lt;br&gt;
Space Complexity: O(1) since the array has a fixed size of 26 characters (assuming only lowercase letters are used in the strings).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leetcode.com/problems/two-sum/"&gt;1. Two Sum&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This is a beginner problem which helps demonstrate how we can use hashmap and a little Math sense to take our time complexity from O(n^2) to O(n)&lt;/p&gt;

&lt;p&gt;Solution:&lt;/p&gt;

&lt;p&gt;We iterate over the array of integers and for each number, we check if its complement (target - number) already exists in the hash map. If it does, we have found a pair of numbers that add up to the target. If it doesn't, we can add the current number to the hash map and continue iterating.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;twoSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;complement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;complement&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;complement&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;twoSum&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;3&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//outputs [1, 2]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Time Complexity:&lt;/p&gt;

&lt;p&gt;The time complexity of the above algorithm is O(n), where n is the length of the array of integers nums. This is because we traverse the array only once.&lt;/p&gt;

&lt;p&gt;Space Complexity:&lt;/p&gt;

&lt;p&gt;The space complexity of the above algorithm is O(n), because we store at most n key-value pairs in the hash map.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leetcode.com/problems/isomorphic-strings/"&gt;205. Isomorphic Strings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a beginner problem demonstrating how intelligent mapping technique can be used to solve complex problems&lt;/p&gt;

&lt;p&gt;Solution:&lt;/p&gt;

&lt;p&gt;To solve this problem, we need to find a way to map each character in s to a character in t. We can do this by using two hash maps - one to map characters from s to t, and another to map characters from t to s.&lt;/p&gt;

&lt;p&gt;We iterate over each character in s and t, and for each character, we check if it has been mapped before. If it has been mapped before, we check if the mapping is the same in both s and t. If it is not, we return false. If the character has not been mapped before, we add it to the hash map.&lt;/p&gt;

&lt;p&gt;We return true if all characters have been checked and the condition is satisfied.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isIsomorphic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;charS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;mapST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;charS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;charT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapTS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;charT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;mapTS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;charT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;charS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nx"&gt;mapST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;charS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;charT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;mapTS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;charT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;charS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Time Complexity:&lt;/p&gt;

&lt;p&gt;The time complexity of this solution is O(n), where n is the length of the input strings s and t. We iterate over each character in s and t only once.&lt;/p&gt;

&lt;p&gt;Space Complexity:&lt;/p&gt;

&lt;p&gt;The space complexity of this solution is also O(n), where n is the length of the input strings s and t. We create two hash maps to store the mappings between characters from s to t and from t to s. The maximum size of these hash maps is n.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What makes PostgreSQL king of databases</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Fri, 28 Jul 2023 06:27:43 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/what-makes-postgresql-king-of-databases-4hkp</link>
      <guid>https://forem.com/sumitbhanushali/what-makes-postgresql-king-of-databases-4hkp</guid>
      <description>&lt;p&gt;According to the StackOverflow survey, PostgreSQL is the most loved database in 2022. What makes it so special? I mean it is just another SQL database, right? let’s find out&lt;/p&gt;

&lt;p&gt;Well first, let's clear out that PostgreSQL is ACID-compliant which is the primary requirement of relational databases and it supports foreign keys, stored procedures, joins, and views too just like MySQL&lt;/p&gt;

&lt;p&gt;When we think of relational databases, MySQL is the first thing that comes to mind. When we google MySQL vs PostgreSQL, it spits out “MySQL is a purely relational database, whereas PostgreSQL is an object-relational database.”&lt;/p&gt;

&lt;p&gt;Object Relational Database?&lt;br&gt;
Objects, Classes and Inheritance are directly supported in database schemas and in the query language. In addition, just as with pure relational systems, it supports extension of the data model with custom data types and methods. This is what makes PostgreSQL so useful, it helps in solving several use cases that would have otherwise required us to learn new database systems like&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OLTP (Online Transaction Processing):&lt;/strong&gt;&lt;br&gt;
Traditional CRUD (Create-Read-Update-Delete) operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OLAP (Online Analytical Processing):&lt;/strong&gt;&lt;br&gt;
OLAP is used by data engineers to analyze and get insights into data.&lt;br&gt;
Since PostgreSQL is based on HTAP (Hybrid transactional/analytical processing) architecture, it can handle OLAP pretty well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FDW (Foreign Data Wrapper):&lt;/strong&gt;&lt;br&gt;
We can create or use FDW to connect to different databases like Redis, MySQL, Neo4j and perform data flow operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streaming:&lt;/strong&gt;&lt;br&gt;
PipelineDB extended from PostgreSQL is a time series database that can be used for real time reporting and analytics applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Geospatial:&lt;/strong&gt;&lt;br&gt;
PostGIS is a spatial database extender for PostgreSQL. It adds support for geographic objects, allowing location queries to be run in SQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time Series:&lt;/strong&gt;&lt;br&gt;
Timescale extended from PostgreSQL for time series and analytics. It is used to combine relentless streams of financial and tick data with other business data to build new apps and uncover unique insights.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distributed Tables:&lt;/strong&gt;&lt;br&gt;
Distributed Tables are tables whose rows are spanned across multiple tables to speed up read and write operations. This is done using a consistent hashing technique. CitusData extended from PostgreSQL gives this feature out of the box&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Scaling your Backend: Database (Master - Slave Replication)</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Mon, 24 Jul 2023 06:28:46 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/scaling-your-backend-database-master-slave-replication-5f4a</link>
      <guid>https://forem.com/sumitbhanushali/scaling-your-backend-database-master-slave-replication-5f4a</guid>
      <description>&lt;p&gt;When you notice that your server is taking more time to respond to the client, your first step should be to find out any wrongly written slow performing code on the API server. If all checks out well, next you look at any slow performing database queries. Generally, queries can be optimized by reducing unnecessary joins or by adding indexes where required (too many indexes can slow down write operations).&lt;/p&gt;

&lt;p&gt;After performing these checks and fixing these if you still want to improve speed then the next step would be to upgrade your database server because in a typical web app, databases become the bottleneck, so databases should be the first which should be scaled vertically.&lt;/p&gt;

&lt;p&gt;After you hit the vertical limit of the server, your next step would be to scale horizontally. Databases are usually read heavy, having a read to write ratio of approximately 90:10. The easiest and best way to scale such a database would be to adopt master slave replication architecture. In this setting, all writes are applied to the master database and all reads go to slave databases. We can have any number of slave replicas as we need. Writes happening at master are synchronized to slave databases in a few milliseconds. In a case when the Master database goes down, one of the slave database is promoted to master using the leader election algorithm.&lt;/p&gt;

&lt;p&gt;There are 3 types of Replication Strategies, you can choose one of them depending on your use case:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Synchronous Replication:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Synchronous Replication, once the Master node updates its copy of the data, it initiates the write operation on its replicas. Once the Replicas receive the update, they apply the change to their copy of data and then send the confirmation to the Master. Once the Master receives the confirmation from all the Replicas, it responds to the client and completes the operation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asynchronous Replication:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Asynchronous Replication, once the Master node updates its copy of the data, it immediately completes the operation by responding to the Client. It does not wait for the changes to be propagated to the Replicas, thus minimizing the block for the Client and maximizing the throughput.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semi-synchronous Replication:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Semi-synchronous Replication, which sits right between the Synchronous and Asynchronous Replication strategies, once the Master node updates its copy of the data, it synchronously replicates the data to a subset of Replicas and asynchronously to others.&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>systemdesign</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>Never forget ACID again!!</title>
      <dc:creator>Sumit Bhanushali</dc:creator>
      <pubDate>Sun, 23 Jul 2023 08:55:20 +0000</pubDate>
      <link>https://forem.com/sumitbhanushali/never-forget-acid-again-1g69</link>
      <guid>https://forem.com/sumitbhanushali/never-forget-acid-again-1g69</guid>
      <description>&lt;p&gt;We often forget how ACID properties function individually since these are the core of Relational Databases it is important we know their importance to ensure clear communication between team members and to use those properties efficiently&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atomicity:&lt;/strong&gt; All or nothing. This property makes sure that in a transaction either all changes are committed or if something fails all changes are reverted.&lt;/p&gt;

&lt;p&gt;A great example of seeing why it is critical to have atomicity is Money Transfers.&lt;/p&gt;

&lt;p&gt;Imagine transferring money from bank account A to B. The transaction involves subtracting the balance from A and adding the balance to B. If any of these changes are partially applied to the database, it will lead to money either not being debited or credited, depending on when it failed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistency:&lt;/strong&gt; This property makes sure that every data in the database is correct. Any attempt to add incorrect data will cause failure.&lt;/p&gt;

&lt;p&gt;What does inconsistent data look like? The balance of an account can be updated as negative which is not possible in the real-world Leftover of orphaned data such as comments on a blog post. If a blog post is deleted, its comments must also be deleted from the database&lt;/p&gt;

&lt;p&gt;Correctness is ensured by defining rules such as Foreign Key constraints, Check constraints, On Delete Cascades, On Update Cascades, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Isolation:&lt;/strong&gt; This property ensures that no more than one transaction can have write(exclusive lock) or read(shared lock) access to a particular row to prevent incorrectly updating data and phantom reads.&lt;/p&gt;

&lt;p&gt;Take a case when two or more transfers happen on the same account simultaneously, without isolation there will be a high probability that the wrong amount is updated in the database and there will be a mismatch between the amount debited and the amount credited&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Durability:&lt;/strong&gt; This property ensures that once the transactions commit, the changes survive any outages, crashes, and failures, which means any writes that have gone through as part of the successful transaction should never abruptly vanish.&lt;/p&gt;

&lt;p&gt;A typical example of this is your purchase order placed on Amazon, which should continue to exist and remain unaffected even after their database faced an outage. So, to ensure something outlives a crash, it has to be stored in non-volatile storage like a Disk; and this forms the core idea of durability.&lt;/p&gt;

&lt;p&gt;Now that you know what ACID properties are and how to use them effectively, Do you ever wonder how they are implemented under the hood?&lt;/p&gt;

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

&lt;p&gt;Most databases implement Atomicity using logging. When a transaction starts, the engine starts logging all changes in a file. When the engine receives COMMIT it then applies those changes permanently. If it receives ROLLBACK or some error happens, that log file is discarded and thus no changes get applied.&lt;/p&gt;

&lt;p&gt;Alternatively, Atomicity can also be implemented by keeping a copy of the data before starting the transaction and using it during rollbacks.&lt;/p&gt;

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

&lt;p&gt;Integrity constraints like primary key, foreign key and datatype checks are checked at runtime when the changes are being applied to the data.&lt;/p&gt;

&lt;p&gt;Cascade operations i.e operations to be performed when data containing foreign keys are modified are performed synchronously along with the running transaction. Most database engines also provide a way to make them asynchronous, allowing us to keep our transactions leaner.&lt;/p&gt;

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

&lt;p&gt;A transaction before altering any row takes a lock (shared or exclusive) on that row, disallowing any other transaction to act on it. The other transactions might have to wait until the first one either commits or rollbacks.&lt;/p&gt;

&lt;p&gt;The granularity and the scope of locking depend on the isolation level configured. Every database engine supports multiple Isolation levels, which determines how stringent the locking is. The 4 isolation levels are&lt;/p&gt;

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

&lt;p&gt;The Serializable isolation level provides the strictest transaction isolation. This level emulates serial transaction execution for all committed transactions; as if transactions had been executed one after another, serially, rather than concurrently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repeatable reads:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Repeatable Read isolation level only sees data committed before the transaction began; it never sees either uncommitted data or changes committed during transaction execution by concurrent transactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read committed:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Read Committed is the default isolation level in PostgreSQL. When a transaction uses this isolation level, a SELECT query (without a FOR UPDATE/SHARE clause) sees only data committed before the query began; it never sees either uncommitted data or changes committed during query execution by concurrent transactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read uncommitted:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The uncommitted read isolation level allows an application to access the uncommitted changes of other transactions. Moreover, UR does not prevent another application from accessing a row that is being read, unless that application is attempting to alter or drop the table.&lt;/p&gt;

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

&lt;p&gt;The most fundamental way to achieve durability is by using a fast transactional log. The changes to be made to the actual data are first flushed on a separate transactional log and then the actual update is made.&lt;/p&gt;

&lt;p&gt;This flushed transactional log enables us to reprocess and replay the transaction during database reboot and reconstruct the system's state to the one that it was in right before the failure occurred - typically the last consistent state of the database. The write to a transaction log is made fast by keeping the file append-only and thus minimizing the disk seeks.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>systemdesign</category>
    </item>
  </channel>
</rss>
