<?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: Huy V</title>
    <description>The latest articles on Forem by Huy V (@khanhhuy).</description>
    <link>https://forem.com/khanhhuy</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%2F395860%2F159cc4a3-ee6c-443e-ad22-1a0afb3de03d.jpeg</url>
      <title>Forem: Huy V</title>
      <link>https://forem.com/khanhhuy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/khanhhuy"/>
    <language>en</language>
    <item>
      <title>The 5 free tools for taking programming notes</title>
      <dc:creator>Huy V</dc:creator>
      <pubDate>Sat, 07 Oct 2023 14:49:25 +0000</pubDate>
      <link>https://forem.com/khanhhuy/the-5-free-tools-for-taking-programming-notes-19po</link>
      <guid>https://forem.com/khanhhuy/the-5-free-tools-for-taking-programming-notes-19po</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Programming is mentally demanding, and effective note-taking is key for software engineers.&lt;/p&gt;

&lt;p&gt;Good notes aid in writing better code, organizing thoughts, creating abstractions, and documenting work progress.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore four free tools that significantly enhance the note-taking experience for programmers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 2 approaches for taking programming notes
&lt;/h2&gt;

&lt;p&gt;Before we delve into comparing the tools, let's clarify what we mean by "taking programming notes."&lt;br&gt;
To keep things simple, I'll categorize the use cases into two groups:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Taking notes outside coding session&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This often happens when we need to do some research beforehand, give comparison for technical approaches, or write documentation for others to understand/maintain the code&lt;/p&gt;

&lt;p&gt;Most note-taking tools available today can be used for this purpose. However, since we're dealing with code, having a "code block" feature is essential in these tools.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;foo&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bar&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;Taking notes while coding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When we're adding new features to our code, it's common to have to read through existing code written by someone else. This helps us understand what the existing code does and where our new code should go.&lt;/p&gt;

&lt;p&gt;Sometimes, the code can be very complex and spread out across multiple files, making it difficult to remember the flow of the code in our minds.&lt;/p&gt;

&lt;p&gt;That's when it becomes helpful to have a scratchpad where we can quickly write down the main ideas about the code and create a high-level understanding of it.&lt;/p&gt;

&lt;p&gt;Although there aren't many tools on the Internet specifically designed for this purpose, we'll soon explore a few of them.&lt;/p&gt;



&lt;p&gt;Let’s explore the 1st category&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Markdown and VSCode
&lt;/h2&gt;

&lt;p&gt;This is a straightforward and accessible tool for taking notes. Don't underestimate its simplicity—VSCode is a powerful and fast editor with many customization options. It allows you to write and view Markdown files simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XzyfL31o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ler0xlrd9wtcs5enky5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XzyfL31o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ler0xlrd9wtcs5enky5v.png" alt="Markdown and VSCode" width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some benefits you may like with this setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can enhance your Markdown writing experience by installing various extensions, such as the following:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one"&gt;https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;You can choose any color theme you prefer.&lt;/li&gt;
&lt;li&gt;The code block formatting is handled by VSCode, ensuring good readability&lt;/li&gt;
&lt;li&gt;Searching and finding content within your notes is quick and effortless.&lt;/li&gt;
&lt;li&gt;One standout feature of this setup is the ability to open two workspaces simultaneously inside VSCode.

&lt;ul&gt;
&lt;li&gt;You can create a separate workspace for your notes and include it in the workspace that contains your coding repository.&lt;/li&gt;
&lt;li&gt;This way, you can easily open Markdown files and copy code from your repository without any hassle.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/docs/editor/workspaces"&gt;https://code.visualstudio.com/docs/editor/workspaces&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


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

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

&lt;p&gt;&lt;a href="https://www.notion.so/"&gt;https://www.notion.so/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nowadays, Notion is very popular, so you might already be familiar with it.&lt;/p&gt;

&lt;p&gt;It is a comprehensive note-taking application that offers features that surpass the combination of VSCode and Markdown. &lt;/p&gt;

&lt;p&gt;Notion is a cloud-based tool, so sharing and collaborating is well supported&lt;/p&gt;

&lt;p&gt;Notion's code block supports numerous programming languages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3P7wUgtu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nn2z0c1ds2ngu2iw632l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3P7wUgtu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nn2z0c1ds2ngu2iw632l.png" alt="Notion" width="726" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://obsidian.md/"&gt;https://obsidian.md/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Obsidian is a really interesting tool. I would describe it as a note-taking app that resembles an offline version of Notion, but with the ability to install many plugins (similar to VSCode extensions). &lt;/p&gt;

&lt;p&gt;The code block in Obsidian is awesome just like Notion&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bnW3cW6Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lol0m7li4u7fetsto0s7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bnW3cW6Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lol0m7li4u7fetsto0s7.png" alt="Obsidian" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recently, Obsidian introduced the canvas feature, which is ideal for drawing code architectures. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--82cRLQX---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stebt8zfxel4d429fme8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--82cRLQX---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stebt8zfxel4d429fme8.png" alt="Obsidian Canvas" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Obsidian is an offline application with its own advantages and disadvantages. The search function on Obsidian is extremely fast compared to Notion. However, when it comes to sharing and collaborating, Notion is far superior to Obsidian.&lt;/p&gt;

&lt;p&gt;Chance that you already use a note-taking app like Notion and Obsidian, so unless the tool doesn’t support code block, then you can use any note-taking tool for organizing your programming notes&lt;/p&gt;




&lt;p&gt;Let’s explore the 2nd category: Taking notes while coding&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Code Annotation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=tkcandrade.code-annotation&amp;amp;ssr=false#review-details"&gt;https://marketplace.visualstudio.com/items?itemName=tkcandrade.code-annotation&amp;amp;ssr=false#review-details&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first tool in the list is this small but useful VSCode extension&lt;/p&gt;

&lt;p&gt;Here's what it does: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;While coding, you can use the "Code Annotation: Add Note" command to add notes&lt;/li&gt;
&lt;li&gt;The extension stores your notes with the path to the original file&lt;/li&gt;
&lt;li&gt;Later, you can view all your notes in a Markdown file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tool is useful if you don't want to clutter your code with inline "TODO: ..." comments.&lt;/p&gt;

&lt;p&gt;It also allows you to have a better summary of all your notes at the end of the day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sEwhIvVj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/khanhhuy/image/upload/v1696687522/codediagram/blogs/20231007-5free-code-annotation_oqhsbn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sEwhIvVj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/khanhhuy/image/upload/v1696687522/codediagram/blogs/20231007-5free-code-annotation_oqhsbn.png" alt="Code Annotation" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, you can simply create a Markdown file to store your notes, although it's slightly less convenient compared to using Code Annotation.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Code Diagram
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.codediagram.io/"&gt;https://www.codediagram.io/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=CodeDiagram.codediagram"&gt;https://marketplace.visualstudio.com/items?itemName=CodeDiagram.codediagram&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disclaimer: this is my extension&lt;/p&gt;

&lt;p&gt;Code Diagram is a visual note-taking tool that is integrated within VSCode.&lt;/p&gt;

&lt;p&gt;Instead of using text-based notes, it prefers a visualization-based approach&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GtVOCnlR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/khanhhuy/image/upload/v1696687824/codediagram/blogs/20231007-5free-cd-2_yor0vq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GtVOCnlR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/khanhhuy/image/upload/v1696687824/codediagram/blogs/20231007-5free-cd-2_yor0vq.png" alt="Code Diagram" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It offers a canvas tab where you can add your code blocks and connect them.&lt;/li&gt;
&lt;li&gt;To create a note, just select the code and click on "Snip it."&lt;/li&gt;
&lt;li&gt;This action creates a new box that contains your selected code.&lt;/li&gt;
&lt;li&gt;The box also includes a link to the original code file, so you can open it with a single click.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A key value of Code Diagram is to facilitate the visualization of complex code flows.&lt;/p&gt;

&lt;p&gt;For instance, when tracing a feature that spans multiple files and includes conditional branches, rather than relying on mental tracking, you can dump the code flow into the diagram for improved visualization.&lt;/p&gt;

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

&lt;p&gt;We discussed two use cases for programming notes. The choice of the appropriate tool depends on your needs. You can freely combine and use these tools together to create your optimal setup.&lt;/p&gt;

&lt;p&gt;In the end, what matters most is finding a note-taking workflow that suits your preferences and enhances your productivity.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

</description>
      <category>programming</category>
      <category>notetaking</category>
      <category>visualization</category>
    </item>
    <item>
      <title>A short tour of ExpressJS implementation (Part 1)</title>
      <dc:creator>Huy V</dc:creator>
      <pubDate>Sat, 02 Sep 2023 09:47:37 +0000</pubDate>
      <link>https://forem.com/khanhhuy/a-short-tour-of-expressjs-implementation-part-1-28gd</link>
      <guid>https://forem.com/khanhhuy/a-short-tour-of-expressjs-implementation-part-1-28gd</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;ExpressJS is a web framework that most of us know about. I really like how easy and fast it is to set up a new server using Express.&lt;/p&gt;

&lt;p&gt;Under the hood, Express is a lightweight wrapper around the Node HTTP module. It abstracts out some complexity of the HTTP module and provides us with a simpler way to build our backend server.&lt;/p&gt;

&lt;p&gt;In this article, I want to understand how Express is implemented and see if I can learn something from that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start reading the codes
&lt;/h2&gt;

&lt;p&gt;The source code of ExpressJS is available at: &lt;a href="https://github.com/expressjs/express"&gt;https://github.com/expressjs/express&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, let's check the directory structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── index.js
├── lib
│   ├── application.js
│   ├── express.js
│   ├── middleware
│   │   ├── init.js
│   │   └── query.js
│   ├── request.js
│   ├── response.js
│   ├── router
│   │   ├── index.js
│   │   ├── layer.js
│   │   └── route.js
│   ├── utils.js
│   └── view.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main codes live in the &lt;code&gt;lib&lt;/code&gt; folder, with a few modules such as: application, middleware, request, response, router… It is indeed simple, there are only a few files compared to other web frameworks.&lt;/p&gt;

&lt;p&gt;Now, we can jump right into the &lt;code&gt;express.js&lt;/code&gt; and read the codes. But I want to &lt;em&gt;approach the reading process in a different way&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let’s say that we have this tiny application that uses Express.&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;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;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;myapp&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="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="nx"&gt;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;whateverLogger&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="nx"&gt;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;/hello&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;res&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="nx"&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;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;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;/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;req&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="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="nx"&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;ok&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;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Example app listening on port &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 can separate this application into 2 phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Phase 1: Registering the handlers&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;In this phase, the handlers (middleware) have been set as follows: &lt;code&gt;whateverLogger&lt;/code&gt;, and the handlers for &lt;code&gt;/hello&lt;/code&gt; and &lt;code&gt;/world&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phase 2: Processing the requests&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;This phase is where the server receives the requests and processes them&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Let’s start reading the source codes following each phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 1: Registering handlers
&lt;/h2&gt;

&lt;p&gt;The main method that we need attention to are the two:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;myapp = express()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;myapp.use()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the &lt;code&gt;express()&lt;/code&gt; my first guess is to read the &lt;code&gt;express.js&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  express.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;./application&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;./router/route&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&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;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;./router&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;exports&lt;/span&gt; &lt;span class="o"&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="nx"&gt;createApplication&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createApplication&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;app&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;req&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;next&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="nx"&gt;handle&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;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;mixin&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="nx"&gt;EventEmitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&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;mixin&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="nx"&gt;proto&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="p"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(omitted other details for clarity)&lt;/p&gt;

&lt;p&gt;The function call returns an &lt;code&gt;app&lt;/code&gt; which is also a function. The &lt;code&gt;mixin(app, proto, false)&lt;/code&gt; indicates that most of the logic of this &lt;code&gt;app&lt;/code&gt; will reside in the  &lt;code&gt;./application&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can skip the mixin logic and assume that its purpose is to add methods and properties to the &lt;code&gt;app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Our next hop is the &lt;code&gt;application.js&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  application.js
&lt;/h3&gt;

&lt;p&gt;At line 194, we can see the &lt;code&gt;app.use&lt;/code&gt; is defined:&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="p"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;var&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;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;./router&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="nx"&gt;use&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="nx"&gt;fns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&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;fn&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handle&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fn&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="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&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;There are many activities in this method but the first thing that should catch our eyes is the &lt;code&gt;fns.forEach&lt;/code&gt; that calls the &lt;code&gt;router.use(path, fn)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.use&lt;/code&gt; receives a list of functions (that are our handlers for a path). Then register each of those functions using the &lt;code&gt;router&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now let’s jump to the &lt;code&gt;router.js&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  router.js
&lt;/h3&gt;

&lt;p&gt;A lot of interesting things happen in this file.&lt;/p&gt;

&lt;p&gt;First, the constructor codes show a &lt;code&gt;stack&lt;/code&gt; is defined.&lt;/p&gt;

&lt;p&gt;Whenever I see a stack (or queue), I immediately think of an array that has some sort of order when we insert or access the array.&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;var&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt; &lt;span class="o"&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="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&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;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;router&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;Continue, we find the definition of &lt;code&gt;router.use&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The sweet spot is this for loop where it creates a new &lt;code&gt;Layer&lt;/code&gt; and pushes it to the stack&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="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;callbacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&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;callbacks&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;var&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;callbacks&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;layer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;sensitive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;caseSensitive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;strict&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="na"&gt;end&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;fn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;layer&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Each item on the stack is a &lt;code&gt;Layer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;Layer&lt;/code&gt; can only receive a &lt;code&gt;path&lt;/code&gt; and a &lt;code&gt;fn&lt;/code&gt; callback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now at this point, I can imagine how this setup is stored in the stack:&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="nx"&gt;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;/hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;/world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will become:&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="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nx"&gt;Layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;Layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;Layer&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;Layer&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- index: 0&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I believe we now have a basic understanding of how the registration process works, and what is the data structure behind the scence&lt;/p&gt;

&lt;p&gt;Before moving on to Phase 2, here's a diagram to summarize everything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eKPmUcQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/khanhhuy/image/upload/v1693645817/codediagram/Screenshot_2023-09-02_at_16.10.03_kegut9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eKPmUcQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/khanhhuy/image/upload/v1693645817/codediagram/Screenshot_2023-09-02_at_16.10.03_kegut9.png" alt="Summary of phase 1: registering handlers" width="609" height="1276"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.codediagram.io/app/shares?token=5dce1a36"&gt;https://www.codediagram.io/app/shares?token=5dce1a36&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;Phase 2: Processing the requests&lt;/strong&gt;, we’ll focus on how a request is processed through the middleware by looking into the implementation of the &lt;code&gt;next()&lt;/code&gt; function&lt;/p&gt;

&lt;p&gt;Please stay tune 😄&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>node</category>
      <category>express</category>
    </item>
    <item>
      <title>A short tour of ExpressJS implementation (Part 1)</title>
      <dc:creator>Huy V</dc:creator>
      <pubDate>Sat, 02 Sep 2023 09:37:35 +0000</pubDate>
      <link>https://forem.com/khanhhuy/a-short-tour-of-expressjs-implementation-part-1-53ie</link>
      <guid>https://forem.com/khanhhuy/a-short-tour-of-expressjs-implementation-part-1-53ie</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;ExpressJS is a web framework that most of us know about. I really like how easy and fast it is to set up a new server using Express.&lt;/p&gt;

&lt;p&gt;Under the hood, Express is a lightweight wrapper around the Node HTTP module. It abstracts out some complexity of the HTTP module and provides us with a simpler way to build our backend server.&lt;/p&gt;

&lt;p&gt;In this article, I want to understand how Express is implemented and see if I can learn something from that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start reading the codes
&lt;/h2&gt;

&lt;p&gt;The source code of ExpressJS is available at: &lt;a href="https://github.com/expressjs/express"&gt;https://github.com/expressjs/express&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, let's check the directory structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── index.js
├── lib
│   ├── application.js
│   ├── express.js
│   ├── middleware
│   │   ├── init.js
│   │   └── query.js
│   ├── request.js
│   ├── response.js
│   ├── router
│   │   ├── index.js
│   │   ├── layer.js
│   │   └── route.js
│   ├── utils.js
│   └── view.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main codes live in the &lt;code&gt;lib&lt;/code&gt; folder, with a few modules such as: application, middleware, request, response, router… It is indeed simple, there are only a few files compared to other web frameworks.&lt;/p&gt;

&lt;p&gt;Now, we can jump right into the &lt;code&gt;express.js&lt;/code&gt; and read the codes. But I want to &lt;em&gt;approach the reading process in a different way&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let’s say that we have this tiny application that uses Express.&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;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;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;myapp&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="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="nx"&gt;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;whateverLogger&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="nx"&gt;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;/hello&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;res&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="nx"&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;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;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;/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;req&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="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="nx"&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;ok&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;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Example app listening on port &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 can separate this application into 2 phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Phase 1: Registering the handlers&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;In this phase, the handlers (middleware) have been set as follows: &lt;code&gt;whateverLogger&lt;/code&gt;, and the handlers for &lt;code&gt;/hello&lt;/code&gt; and &lt;code&gt;/world&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phase 2: Processing the requests&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;This phase is where the server receives the requests and processes them&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Let’s start reading the source codes following each phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 1: Registering handlers
&lt;/h2&gt;

&lt;p&gt;The main method that we need attention to are the two:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;myapp = express()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;myapp.use()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the &lt;code&gt;express()&lt;/code&gt; my first guess is to read the &lt;code&gt;express.js&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  express.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;./application&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;./router/route&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&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;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;./router&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;exports&lt;/span&gt; &lt;span class="o"&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="nx"&gt;createApplication&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createApplication&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;app&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;req&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;next&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="nx"&gt;handle&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;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;mixin&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="nx"&gt;EventEmitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&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;mixin&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="nx"&gt;proto&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="p"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(omitted other details for clarity)&lt;/p&gt;

&lt;p&gt;The function call returns an &lt;code&gt;app&lt;/code&gt; which is also a function. The &lt;code&gt;mixin(app, proto, false)&lt;/code&gt; indicates that most of the logic of this &lt;code&gt;app&lt;/code&gt; will reside in the  &lt;code&gt;./application&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can skip the mixin logic and assume that its purpose is to add methods and properties to the &lt;code&gt;app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Our next hop is the &lt;code&gt;application.js&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  application.js
&lt;/h3&gt;

&lt;p&gt;At line 194, we can see the &lt;code&gt;app.use&lt;/code&gt; is defined:&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="p"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;var&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;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;./router&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="nx"&gt;use&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="nx"&gt;fns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&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;fn&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handle&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fn&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="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&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;There are many activities in this method but the first thing that should catch our eyes is the &lt;code&gt;fns.forEach&lt;/code&gt; that calls the &lt;code&gt;router.use(path, fn)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.use&lt;/code&gt; receives a list of functions (that are our handlers for a path). Then register each of those functions using the &lt;code&gt;router&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now let’s jump to the &lt;code&gt;router.js&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  router.js
&lt;/h3&gt;

&lt;p&gt;A lot of interesting things happen in this file.&lt;/p&gt;

&lt;p&gt;First, the constructor codes show a &lt;code&gt;stack&lt;/code&gt; is defined.&lt;/p&gt;

&lt;p&gt;Whenever I see a stack (or queue), I immediately think of an array that has some sort of order when we insert or access the array.&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;var&lt;/span&gt; &lt;span class="nx"&gt;proto&lt;/span&gt; &lt;span class="o"&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="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&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;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;router&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;Continue, we find the definition of &lt;code&gt;router.use&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The sweet spot is this for loop where it creates a new &lt;code&gt;Layer&lt;/code&gt; and pushes it to the stack&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="nx"&gt;proto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;callbacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&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;callbacks&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;var&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;callbacks&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;layer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;sensitive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;caseSensitive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;strict&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="na"&gt;end&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;fn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;layer&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Each item on the stack is a &lt;code&gt;Layer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;Layer&lt;/code&gt; can only receive a &lt;code&gt;path&lt;/code&gt; and a &lt;code&gt;fn&lt;/code&gt; callback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now at this point, I can imagine how this setup is stored in the stack:&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="nx"&gt;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;/hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;myapp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;/world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will become:&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="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nx"&gt;Layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;Layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;Layer&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;Layer&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- index: 0&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I believe we now have a basic understanding of how the registration process works, and what is the data structure behind the scence&lt;/p&gt;

&lt;p&gt;Before moving on to Phase 2, here's a diagram to summarize everything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eKPmUcQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/khanhhuy/image/upload/v1693645817/codediagram/Screenshot_2023-09-02_at_16.10.03_kegut9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eKPmUcQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/khanhhuy/image/upload/v1693645817/codediagram/Screenshot_2023-09-02_at_16.10.03_kegut9.png" alt="Summary of phase 1: registering handlers" width="609" height="1276"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.codediagram.io/app/shares?token=5dce1a36"&gt;https://www.codediagram.io/app/shares?token=5dce1a36&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;Phase 2: Processing the requests&lt;/strong&gt;, we’ll focus on how a request is processed through the middleware by looking into the implementation of the &lt;code&gt;next()&lt;/code&gt; function&lt;/p&gt;

&lt;p&gt;Please stay tune 😄&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How I host everything for my SaaS side-project on a $6 server</title>
      <dc:creator>Huy V</dc:creator>
      <pubDate>Fri, 01 Sep 2023 15:30:37 +0000</pubDate>
      <link>https://forem.com/khanhhuy/how-i-host-everything-for-my-saas-side-project-on-a-6-server-3n75</link>
      <guid>https://forem.com/khanhhuy/how-i-host-everything-for-my-saas-side-project-on-a-6-server-3n75</guid>
      <description>&lt;p&gt;Building side projects, attracting users, and earning some extra income are something I love to do after work.&lt;/p&gt;

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

&lt;p&gt;Since I’m a web developer, many of my ideas have these 4 standard components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A marketing website or a landing page&lt;/li&gt;
&lt;li&gt;A static front-end web app&lt;/li&gt;
&lt;li&gt;An API server&lt;/li&gt;
&lt;li&gt;A database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Being able to ship fast is my ultimate goal to validate the ideas.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problems
&lt;/h2&gt;

&lt;p&gt;My initial idea was to use services that could automate the infrastructure and deployment for me. I tried using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static web hosting (&lt;a href="http://surge.sh/"&gt;Surge.sh&lt;/a&gt;, Firebase) for the landing page and web app&lt;/li&gt;
&lt;li&gt;Google App Engine/Heroku Dyno for the backend and database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tools appealed to me because I could simply type a command on my local machine and everything would get deployed. &lt;/p&gt;

&lt;p&gt;Well, it &lt;em&gt;did&lt;/em&gt; work that way, but when I added more requirements, I often found myself struggling through complex documentation without a clear sense of how they worked.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why couldn't my Node app connect to the database?&lt;/li&gt;
&lt;li&gt;How could I avoid caching the &lt;code&gt;index.html&lt;/code&gt; file on the browser (and only cache assets)?&lt;/li&gt;
&lt;li&gt;How could I point my Cloudflare DNS to the Node app IP?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't get me wrong, these tools are capable of fulfilling my requirements, but with limited time outside of work, I don't want to spend most of my time reading documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 1-server with Nginx solution
&lt;/h2&gt;

&lt;p&gt;My idea is, can I install everything on a virtual machine (similar to my laptop), and use Nginx to redirect traffic?&lt;/p&gt;

&lt;p&gt;Turns out it’s pretty simpler than I thought.&lt;/p&gt;

&lt;p&gt;Here’s the URL mapping of my project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F9f0sBuf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v5jyjje64nmf0q469xys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F9f0sBuf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v5jyjje64nmf0q469xys.png" alt="URL mapping" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;www.codediagram.io/app/&lt;/code&gt; is a static web app, which is a VueJS client-side app. All the assets are served from &lt;code&gt;/opt/front-end-app&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;www.codediagram.io/&lt;/code&gt; is the landing page. This is generated HTML that is optimized for the SEO. All the assets are served from &lt;code&gt;/opt/landing-page&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;api.codediagram.io&lt;/code&gt; is routed to the back-end NodeJS app runs on port 5003&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason that the static front-end app and the landing page have the same subdomain, only separated by subpath, is that these URLs are user-facing, and I want them to be consistent, easy to use, and remember.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is the Nginx config that does all the work:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    server_name www.codediagram.io;

    location / {
        root /opt/landing-page;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    location /app {
        root /opt/front-end-app;
        try_files $uri $uri/ =404;
    }
}

server {
    server_name api.codediagram.io;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://localhost:5003;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_cache_bypass $http_upgrade;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The first server block is for the landing page and the front-end app.&lt;/li&gt;
&lt;li&gt;The second server block is for the Node instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To enable SSL, I highly recommend using Certbot and letting it auto-configure your Nginx config.&lt;/p&gt;

&lt;p&gt;And that's it, everything is set!&lt;/p&gt;

&lt;h2&gt;
  
  
  The half-automated deployment
&lt;/h2&gt;

&lt;p&gt;For the landing page and the front-end app. I wrote a small command to build and copy the build to the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm build \
  ssh server 'rm -rf /opt/front-end-app' \
  scp -r ./.output/public server:/opt/front-end-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the back-end, I manually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSH into the server&lt;/li&gt;
&lt;li&gt;Checkout new codes&lt;/li&gt;
&lt;li&gt;Restarts &lt;a href="https://pm2.keymetrics.io/"&gt;PM2&lt;/a&gt; instances&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The server specs
&lt;/h2&gt;

&lt;p&gt;I’m using Digital Ocean, the 6-dollar droplet is a 1GB RAM, 1vCPU. This is more than I need for now since not many people are using my product.&lt;/p&gt;

&lt;p&gt;You can pick any cloud vendor that you like.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I’ve learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Setting up this environment is similar to setting up a local development on my laptop, with the exception of Nginx.&lt;/li&gt;
&lt;li&gt;Although the Nginx configuration may seem complex at first, all routing logic is contained in that file, making it easier to understand what will happen.&lt;/li&gt;
&lt;li&gt;Having only one server for everything streamlines many processes.&lt;/li&gt;
&lt;li&gt;I can easily replicate this setup for any side project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup is suitable for my use case, which involves a side project with low usage. However, if your project has high usage, then this is not an ideal setup. &lt;/p&gt;

&lt;p&gt;In such cases, it is recommended to split the components into separate servers with backup and high availability features.&lt;/p&gt;

&lt;p&gt;If you're interested, this is the tool that I built: &lt;a href="https://www.codediagram.io/"&gt;https://www.codediagram.io/&lt;/a&gt;&lt;/p&gt;

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

</description>
      <category>webdev</category>
      <category>nginx</category>
      <category>sideprojects</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
