<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: RAM PANDEY</title>
    <description>The latest articles on DEV Community by RAM PANDEY (@rampa2510).</description>
    <link>https://dev.to/rampa2510</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%2F165320%2Fa98ec2c3-5224-4c2c-942a-148640a0b8df.jpeg</url>
      <title>DEV Community: RAM PANDEY</title>
      <link>https://dev.to/rampa2510</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rampa2510"/>
    <language>en</language>
    <item>
      <title>Breaking Down AI Buzzwords: A Developer’s Guide to Understanding the Basics</title>
      <dc:creator>RAM PANDEY</dc:creator>
      <pubDate>Wed, 09 Apr 2025 06:29:48 +0000</pubDate>
      <link>https://dev.to/rampa2510/breaking-down-ai-buzzwords-a-developers-guide-to-understanding-the-basics-1dcf</link>
      <guid>https://dev.to/rampa2510/breaking-down-ai-buzzwords-a-developers-guide-to-understanding-the-basics-1dcf</guid>
      <description>&lt;p&gt;&lt;strong&gt;Hey there, developers!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI is absolutely &lt;em&gt;everywhere&lt;/em&gt; these days, right? And let's be honest, so is the jargon: tokenization, embeddings, self-attention... it's enough to make your head spin! If you've ever found yourself nodding along in a meeting while secretly wondering what these terms &lt;em&gt;really&lt;/em&gt; mean, trust me, you're not alone. I've been there too.&lt;/p&gt;

&lt;p&gt;That's why I wrote this post. My goal is to break down some of the most common AI buzzwords you'll encounter, especially in Large Language Models (LLMs), using plain language. Forget the dense academic papers and overwhelming math for now – we're focusing on simple explanations to help you grasp &lt;em&gt;how&lt;/em&gt; these concepts work and &lt;em&gt;why&lt;/em&gt; they actually matter in the models we use.&lt;/p&gt;

&lt;p&gt;Ready to make sense of the AI hype together? Let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Tokenization: Chopping Up Language&lt;/strong&gt;
&lt;/h2&gt;

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

&lt;p&gt;First things first: before any AI model can even &lt;em&gt;begin&lt;/em&gt; to understand text, it needs to break it down into smaller, manageable pieces. This crucial first step is called &lt;strong&gt;tokenization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's it really doing?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of it like slicing a loaf of bread before you can make sandwiches. You take a whole sentence (the loaf) and chop it into smaller bits – words or even parts of words (the slices). These pieces are called "tokens."&lt;/p&gt;

&lt;p&gt;For example, the sentence &lt;em&gt;"Hello, world!"&lt;/em&gt; might get tokenized into something like:&lt;br&gt;
&lt;code&gt;[Hello] [ , ] [world] [ ! ]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Why bother? Because computers don't speak English, French, or Hindi – they speak the language of numbers. Tokenization is the bridge. Each token gets assigned a numerical ID, turning language into a format the machine can actually perform calculations on.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A Simple Analogy:&lt;/strong&gt; I found it helpful to think of reading a complex recipe. You don't tackle it all at once; you break it down ingredient by ingredient, step by step. Tokenization does this for language, making it digestible for the AI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Things to Remember about Tokenization:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Vocab Size Matters:&lt;/strong&gt; Every model has a pre-defined "vocabulary" – a list of all the unique tokens it recognizes. This might include letters (A-Z, a-z), numbers (0-9), punctuation, common words, or subwords. If a model's vocab size is, say, 50,000, it knows 50,000 unique pieces it can represent numerically.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Different Models, Different Strategies:&lt;/strong&gt; Some models tokenize purely by words (&lt;code&gt;[Hello]&lt;/code&gt;, &lt;code&gt;[world]&lt;/code&gt;). Others use "subword" tokenization, which is really clever. It can break down unknown or long words into smaller known parts, like tokenizing &lt;em&gt;"Unbelievable"&lt;/em&gt; into &lt;code&gt;[Un] [believ] [able]&lt;/code&gt;. This helps handle new words without needing an infinitely large vocabulary.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why should you care?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tokenization is the absolute foundation. Without it, text remains meaningless squiggles to an AI. It's the essential first step in turning human language into something a machine can process and learn from.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Vector Embeddings: Giving Words Mathematical Meaning&lt;/strong&gt;
&lt;/h2&gt;

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

&lt;p&gt;So, we've chopped our text into tokens and given each a number. But those numbers are just IDs – they don't capture the &lt;em&gt;meaning&lt;/em&gt; or &lt;em&gt;context&lt;/em&gt; of the token. That's where the magic of &lt;strong&gt;vector embeddings&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are they, exactly?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine giving each word (or token) a rich, multi-faceted mathematical identity. Instead of just one ID number, each token gets mapped to a &lt;strong&gt;vector&lt;/strong&gt; – basically, a list of numbers (often hundreds of them!). This vector isn't random; it's carefully calculated to represent the token's meaning and its relationships to other tokens.&lt;/p&gt;

&lt;p&gt;Why vectors? Because while machines don't understand "king" or "queen," they excel at comparing lists of numbers. Embeddings translate semantic meaning into a format computers can work with.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Think of it like this:&lt;/strong&gt; You're plotting concepts on a complex, multi-dimensional map. Each concept (token) gets coordinates (its vector). Crucially, concepts with similar meanings ("king," "queen," "monarch") end up close together on this map. This proximity represents semantic similarity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How do they capture meaning?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Tokens to Vectors:&lt;/strong&gt; Every token from the vocabulary gets its own unique vector. For instance (simplified!):

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;"King"&lt;/em&gt; → &lt;code&gt;[1.2, 3.4, -0.8, ...]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"Queen"&lt;/em&gt; → &lt;code&gt;[1.1, 3.5, -0.7, ...]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Semantic Relationships:&lt;/strong&gt; These vectors are learned in a way that captures relationships. A famous example is that the vector math &lt;code&gt;vector("King") - vector("Man") + vector("Woman")&lt;/code&gt; often results in a vector very close to &lt;code&gt;vector("Queen")&lt;/code&gt;. This shows the model has learned gender and royalty relationships!&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Finding Similarities:&lt;/strong&gt; Because similar concepts cluster together, the model can find related ideas just by looking for vectors that are "close" in this mathematical space. "Cat" will be nearer to "dog" than to "car."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why are embeddings so important?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vector embeddings are critical for AI to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Grasp relationships between words (synonyms, analogies, concepts).&lt;/li&gt;
&lt;li&gt; Power recommendation systems (finding "similar" items).&lt;/li&gt;
&lt;li&gt; Understand context and nuance far beyond simple keyword matching.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without embeddings, AI would struggle to understand the rich tapestry of meaning woven into human language. They are the secret sauce for capturing semantics.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Positional Encoding: Keeping Track of Word Order&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Okay, we have meaningful vectors for our tokens. But there's a big problem, especially for newer models like Transformers: they look at all the tokens in a sentence &lt;em&gt;simultaneously&lt;/em&gt;. This is great for speed, but it means they might lose track of the original word order.&lt;/p&gt;

&lt;p&gt;Consider &lt;em&gt;"The cat chased the dog"&lt;/em&gt; vs. &lt;em&gt;"The dog chased the cat."&lt;/em&gt; Same tokens, same embeddings, but completely different meanings! How do we solve this? Enter &lt;strong&gt;positional encoding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Positional encoding is a clever trick to inject information about a token's &lt;em&gt;position&lt;/em&gt; in the sequence directly into its embedding. It modifies the token's vector slightly, giving the model a signal about where that token appeared (first, second, third, etc.).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Analogy Time:&lt;/strong&gt; Imagine numbering the books on your shelf. Even if you pull them all off, the numbers tell you how to put them back in the correct order. Positional encoding gives each token's vector a unique "position number" or signal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How does it work (conceptually)?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Adding Positional Info:&lt;/strong&gt; A unique positional value (itself a vector, often generated using sine and cosine functions of different frequencies) is &lt;em&gt;added&lt;/em&gt; to each token's embedding vector.

&lt;ul&gt;
&lt;li&gt;Token Embedding + Positional Vector = Combined Embedding&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Unique Signal for Each Position:&lt;/strong&gt; The mathematical functions used ensure that each position (1st, 2nd, 3rd...) gets a distinct positional vector pattern that the model can learn to recognize.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Preserving Order:&lt;/strong&gt; Now, even though the model processes tokens in parallel, the combined embeddings contain the necessary clues to understand the original sequence and differentiate &lt;em&gt;"cat chased dog"&lt;/em&gt; from &lt;em&gt;"dog chased cat."&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why is this necessary?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Older models like RNNs processed words one by one, inherently keeping track of order. Transformers, by processing tokens in parallel for speed and capturing long-range dependencies better, lose this built-in sequential awareness. Positional encoding adds it back explicitly. It's like giving the Transformer a GPS for the sentence structure. Without it, meaning derived from word order would be lost.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Self-Attention: Understanding Context Within a Sentence&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;How do &lt;em&gt;you&lt;/em&gt; understand the meaning of "bank" in &lt;em&gt;"The bank is near the river"&lt;/em&gt; versus &lt;em&gt;"I need to go to the bank to deposit this check"&lt;/em&gt;? You use &lt;strong&gt;context&lt;/strong&gt; – the surrounding words. &lt;strong&gt;Self-attention&lt;/strong&gt; is the mechanism that allows AI models, particularly Transformers, to do the same thing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Self-Attention?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's a process that lets the model weigh the importance of &lt;em&gt;all&lt;/em&gt; other tokens in the input sequence when processing a specific token. Instead of looking at words in isolation, the model "attends" to the relationships between them to better understand the context-dependent meaning.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A Human Parallel:&lt;/strong&gt; Think of a group discussion. When someone says a potentially ambiguous word like "address," you pay attention to the rest of their sentence ("Do you need my home address?" vs. "How should I address this issue?") to get the real meaning. Self-attention lets the model do this internal "listening" across the sentence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How does it work (the gist)?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Token Interactions:&lt;/strong&gt; For every single token, the model calculates an "attention score" between it and &lt;em&gt;every other token&lt;/em&gt; (including itself) in the sequence. This score represents how relevant token B is for understanding token A in this specific context.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Calculating Weighted Importance:&lt;/strong&gt; High scores mean strong relevance, low scores mean weak relevance. For &lt;em&gt;"The bank is near the river,"&lt;/em&gt; the token "river" would likely get a high attention score when the model processes "bank."&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Refining Embeddings:&lt;/strong&gt; The model then recalculates each token's embedding by creating a weighted sum of all tokens' embeddings, guided by these attention scores. This means the final representation of "bank" is heavily influenced by the representation of "river," helping it resolve ambiguity.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why is this a game-changer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Language is slippery! Words change meaning based on context. Self-attention gives models the power to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Disambiguate words:&lt;/strong&gt; Understand "bank" (river) vs. "bank" (financial).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Understand relationships:&lt;/strong&gt; Figure out what pronouns like "it" or "they" refer to earlier in the text.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Grasp the holistic meaning&lt;/strong&gt; of a sentence rather than just processing word-by-word.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's fundamental to how modern AI truly &lt;em&gt;understands&lt;/em&gt; language nuances.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Multi-Head Attention: Looking at Context from Multiple Angles&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Self-attention is powerful, letting tokens consider context. But what if one perspective isn't enough? What if different &lt;em&gt;types&lt;/em&gt; of relationships are important? That's the idea behind &lt;strong&gt;multi-head attention&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of calculating attention just once, multi-head attention performs the self-attention process multiple times in parallel, using different, learned "perspectives" or "heads." Each head can potentially focus on different aspects of the relationships between tokens.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Analogy Upgrade:&lt;/strong&gt; Remember the group meeting analogy for self-attention? Multi-head attention is like having &lt;em&gt;multiple&lt;/em&gt; subgroups in that meeting, each analyzing the project from a specific angle (budget, timeline, resources, technical feasibility). Afterwards, they combine their findings for a much richer, comprehensive understanding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How does it enhance self-attention?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Splitting and Projecting:&lt;/strong&gt; The original token embeddings are split and transformed (projected) differently for each "head."&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Parallel Attention:&lt;/strong&gt; Each head performs the self-attention calculation independently on its transformed version of the embeddings. This allows different heads to learn to focus on different things:

&lt;ul&gt;
&lt;li&gt;One head might capture subject-verb relationships.&lt;/li&gt;
&lt;li&gt;Another might focus on how adjectives modify nouns.&lt;/li&gt;
&lt;li&gt;A third might track long-distance dependencies.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Combining the Insights:&lt;/strong&gt; The outputs from all the attention heads are combined (concatenated and projected again) to produce the final output for that layer. This final representation benefits from the diverse perspectives captured by the individual heads.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why bother with multiple heads?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Language is complex! A single attention mechanism might latch onto the most obvious relationship but miss others. Multi-head attention allows the model to simultaneously consider various types of syntactic and semantic relationships, leading to a deeper and more robust understanding of the input text. It's a key ingredient in the success of powerful models like Transformers for tasks demanding nuanced understanding (translation, summarization, etc.).&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Transformers: The Architecture Powering Modern AI&lt;/strong&gt;
&lt;/h2&gt;

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

&lt;p&gt;You've likely heard of ChatGPT, BERT, Google Translate, DALL·E... These incredible AI systems often have one thing in common under the hood: the &lt;strong&gt;Transformer&lt;/strong&gt; architecture. Introduced in the seminal paper "Attention Is All You Need," Transformers revolutionized how we process sequential data, especially language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a Transformer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's a specific type of neural network architecture designed primarily for sequence-to-sequence tasks (like translation or summarization). Its defining characteristics are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Parallel Processing:&lt;/strong&gt; Unlike older models (RNNs/LSTMs) that process sequences word-by-word, Transformers can process all tokens in a sequence simultaneously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Attention Mechanisms:&lt;/strong&gt; They heavily rely on &lt;strong&gt;self-attention&lt;/strong&gt; and &lt;strong&gt;multi-head attention&lt;/strong&gt; (which we just discussed!) to understand context and relationships between tokens, regardless of their distance in the sequence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Positional Encoding:&lt;/strong&gt; They use positional encodings to keep track of word order, compensating for the parallel processing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Big Picture:&lt;/strong&gt; Think of a Transformer as a highly efficient information processing pipeline, built specifically to leverage attention mechanisms for understanding complex dependencies in data like text.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Core Components Often Include:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Input Processing:&lt;/strong&gt; Tokenization, embedding generation, and adding positional encoding.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Encoder:&lt;/strong&gt; A stack of layers (often including multi-head attention and feed-forward networks) that processes the input sequence and builds a rich, context-aware representation.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Decoder:&lt;/strong&gt; Another stack of layers that takes the encoder's output and generates the target sequence (e.g., the translated sentence), also using attention mechanisms. (More on this next!)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why are Transformers so dominant?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Efficiency &amp;amp; Speed:&lt;/strong&gt; Parallel processing makes them much faster to train on modern hardware (GPUs/TPUs) compared to sequential RNNs.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Superior Context Handling:&lt;/strong&gt; Self-attention excels at capturing long-range dependencies (connecting words far apart in a text) which was a struggle for older models.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Scalability:&lt;/strong&gt; They scale remarkably well with more data and larger model sizes, leading to increasingly powerful AI capabilities.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Transformers are the backbone of much of the current AI revolution in natural language processing and beyond.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Encoder and Decoder: The Two Halves of Many Transformers&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Many Transformer models, especially those used for tasks like machine translation or summarization, consist of two main parts working in tandem: the &lt;strong&gt;encoder&lt;/strong&gt; and the &lt;strong&gt;decoder&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do they do?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;The Encoder:&lt;/strong&gt; Its job is to &lt;em&gt;understand&lt;/em&gt; the input sequence. It reads the entire input sentence (e.g., English text), uses layers of self-attention to build a rich internal representation that captures the meaning and context, and outputs this representation. Think of it as creating a detailed summary or "meaning vector" of the input.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Decoder:&lt;/strong&gt; Its job is to &lt;em&gt;generate&lt;/em&gt; the output sequence (e.g., the French translation). It takes the encoder's output (the meaning vector) and, typically one token at a time, generates the target sentence. Crucially, the decoder also uses attention mechanisms:

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Self-attention&lt;/em&gt; on the words it has &lt;em&gt;already&lt;/em&gt; generated, to maintain coherence.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Cross-attention&lt;/em&gt; looking back at the &lt;em&gt;encoder's output&lt;/em&gt;, to ensure the generated output stays true to the original input's meaning.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A Communication Analogy:&lt;/strong&gt; Imagine translating a message. The encoder is like carefully reading and fully understanding the original message in English. The decoder is then taking that deep understanding and carefully crafting the message word-by-word in French, constantly referring back to the original meaning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why the split?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This separation of concerns is powerful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The encoder can focus entirely on deeply understanding the source material.&lt;/li&gt;
&lt;li&gt;The decoder can focus entirely on generating fluent and accurate target output, guided by the encoder's understanding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; Not all Transformers have both. Models focused purely on understanding (like BERT) might primarily use the encoder part, while models focused purely on generation (like GPT) might primarily use the decoder part, often pre-trained without a specific encoder input for generation tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Softmax: Making the Final Choice&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When an AI model needs to predict the next word in a sentence or classify something, it usually ends up with a bunch of raw scores (called "logits") for each possible option. But how does it turn those scores into a single, confident choice? That's often the job of the &lt;strong&gt;softmax&lt;/strong&gt; function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does Softmax do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Softmax is a mathematical function that takes a list of raw scores and converts them into a list of &lt;strong&gt;probabilities&lt;/strong&gt; that all add up to 1 (or 100%). It essentially highlights the most likely option while still giving some probability to less likely ones.&lt;/p&gt;

&lt;p&gt;For example, predicting the next word after "How are you...":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raw scores (logits): &lt;code&gt;{"doing": 3.1, "feeling": 2.5, "today": 1.0}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Softmax output (probabilities): &lt;code&gt;{"doing": 0.65, "feeling": 0.30, "today": 0.05}&lt;/code&gt; (approx.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model would then typically choose "doing" as the next word because it has the highest probability (65%).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Voting Analogy:&lt;/strong&gt; Think of it like vote counts in an election. The raw scores are the initial tallies. Softmax converts these into percentages of the total vote, making it clear who the winner is, but also showing the support for other candidates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Key Steps (Simplified):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Exponentiate:&lt;/strong&gt; It makes all scores positive and emphasizes the higher scores (e^score).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Normalize:&lt;/strong&gt; It divides each exponentiated score by the sum of all exponentiated scores, ensuring the results sum to 1.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why is Softmax used?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Interpretability:&lt;/strong&gt; Turns arbitrary scores into meaningful probabilities.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Decision Making:&lt;/strong&gt; Provides a clear basis for choosing the most likely output.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Training:&lt;/strong&gt; It's mathematically convenient for training models using methods like cross-entropy loss.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Softmax is the standard way models often convert internal calculations into final predictions or choices.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Temperature: Dialing Up the AI's Creativity&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When using generative AI, you might notice you can sometimes adjust a setting called &lt;strong&gt;temperature&lt;/strong&gt;. This parameter directly influences &lt;em&gt;how&lt;/em&gt; the model uses the probabilities generated by softmax (or a similar process) when picking the next word. It controls the randomness or "creativity" of the output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Temperature?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Temperature is a scaling factor applied to the logits &lt;em&gt;before&lt;/em&gt; they go into the softmax function.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Low Temperature (e.g., &amp;lt; 1.0, like 0.2):&lt;/strong&gt; Dividing logits by a small number makes the differences between scores &lt;em&gt;larger&lt;/em&gt;. This makes the softmax probability distribution sharper, meaning the model becomes &lt;em&gt;more confident&lt;/em&gt;, &lt;em&gt;more focused&lt;/em&gt;, and &lt;em&gt;more likely&lt;/em&gt; to pick the absolute highest-probability word. The output becomes predictable, deterministic, and sometimes repetitive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High Temperature (e.g., &amp;gt; 1.0, like 1.2):&lt;/strong&gt; Dividing logits by a larger number makes the differences between scores &lt;em&gt;smaller&lt;/em&gt;. This flattens the softmax distribution, meaning probabilities are spread more evenly across different words. The model becomes &lt;em&gt;less confident&lt;/em&gt;, &lt;em&gt;more adventurous&lt;/em&gt;, &lt;em&gt;more random&lt;/em&gt;, and &lt;em&gt;more likely&lt;/em&gt; to pick less common words. The output becomes more surprising, diverse, and creative – but also potentially less coherent or relevant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Temperature = 1.0:&lt;/strong&gt; This is the default, using the original softmax probabilities without modification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creativity Thermostat Analogy:&lt;/strong&gt; Low temp is like sticking strictly to the recipe – safe and predictable. High temp is like improvising in the kitchen – more experimental, potentially brilliant, potentially disastrous!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why control Temperature?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It allows you to tailor the AI's output style:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;low temperature&lt;/strong&gt; for tasks needing accuracy and consistency (e.g., factual summarization, code generation based on strict rules).&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;high temperature&lt;/strong&gt; for tasks benefiting from creativity and diversity (e.g., brainstorming ideas, writing poetry, creating varied chatbot responses).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Temperature gives you a knob to turn, balancing between predictable coherence and creative exploration.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Vocab Size: The AI's Word Dictionary&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We mentioned vocabularies back when discussing tokenization. The &lt;strong&gt;vocab size&lt;/strong&gt; is simply the total number of unique tokens defined in that vocabulary. This number has significant implications for the model's performance and efficiency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What determines Vocab Size?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's determined during the tokenization setup phase, based on the training data and the chosen tokenization strategy (word, subword, character).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A model using &lt;strong&gt;character-level&lt;/strong&gt; tokenization might have a tiny vocab size (e.g., ~100 for English letters, numbers, punctuation).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A model using &lt;strong&gt;word-level&lt;/strong&gt; tokenization needs a huge vocab size (tens or hundreds of thousands) to cover most words.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Subword&lt;/strong&gt; tokenization (like BPE or WordPiece used in many modern LLMs) offers a balance, typically having vocab sizes in the tens of thousands (e.g., 30k - 100k). It can represent common words as single tokens but break down rarer words into known subword pieces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dictionary Analogy:&lt;/strong&gt; Vocab size is like the number of entries in the dictionary the AI carries. More entries mean it recognizes more words directly, but the dictionary gets heavier.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Trade-offs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Small Vocab (e.g., Characters):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Pros:&lt;/em&gt; Can represent &lt;em&gt;any&lt;/em&gt; text, handles typos/new words gracefully. Smaller model embedding layer.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Cons:&lt;/em&gt; Sentences become very long sequences of tokens, potentially harder for the model to capture long-range meaning. Less semantically meaningful units.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Large Vocab (e.g., Words):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Pros:&lt;/em&gt; Shorter sequences, tokens are semantically meaningful.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Cons:&lt;/em&gt; Struggles with unknown words ("out-of-vocabulary" problem). Requires huge memory for the embedding layer.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Medium Vocab (e.g., Subwords):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Pros:&lt;/em&gt; Good balance. Handles rare words by breaking them down. Keeps sequences reasonably short. Most common approach now.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Cons:&lt;/em&gt; Tokenization itself is more complex. Tokens might not always align with intuitive word boundaries.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why does it matter?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vocab size directly impacts the model's size, speed, memory usage, and its ability to handle diverse text. It's a fundamental design choice in building an AI model.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Knowledge Cutoff: The AI's "Last Studied" Date&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Ever asked an AI about a very recent event and gotten a vague answer or information that's clearly outdated? This happens because of the &lt;strong&gt;knowledge cutoff&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The knowledge cutoff is simply the point in time when the data used to &lt;em&gt;train&lt;/em&gt; the AI model was collected. The model generally cannot "know" about events, discoveries, or information that emerged &lt;em&gt;after&lt;/em&gt; this date because it wasn't part of its learning material.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Exam Analogy:&lt;/strong&gt; Imagine studying for a history exam using only textbooks published up to the year 2020. Your knowledge would be "cut off" at 2020; you wouldn't know about major events from 2021 unless you got an updated textbook (or the model is retrained/updated).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why does it exist?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Training is Finite:&lt;/strong&gt; Training these massive models takes enormous resources (data, computation, time). The process has to stop at some point to actually release and use the model.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Static Models:&lt;/strong&gt; Once trained, most large models don't continuously learn from the live internet (though some systems might integrate web search results post-generation). Their core knowledge remains fixed until a significant retraining effort occurs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What's the Impact?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Outdated Info:&lt;/strong&gt; Be critical! AI responses about rapidly evolving topics (current events, latest tech, recent pop culture) might be inaccurate if the event happened after the cutoff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability Varies:&lt;/strong&gt; For stable knowledge (math principles, historical facts before the cutoff, core programming concepts), the cutoff is less relevant. For dynamic knowledge, it's crucial to be aware of.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Always check or ask for the model's knowledge cutoff date if you need up-to-the-minute information!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Wrapping Up&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Phew, that was a lot! But hopefully, terms like tokenization, embeddings, attention, and transformers feel a bit less mysterious now. Understanding these core concepts really helps pull back the curtain on how modern AI, especially LLMs, actually works its magic with language.&lt;/p&gt;

&lt;p&gt;These aren't the &lt;em&gt;only&lt;/em&gt; terms you'll hear, but they form a solid foundation. Keep learning, keep experimenting, and don't be afraid to ask questions! AI is constantly evolving, and being curious is the best way to keep up.&lt;/p&gt;

&lt;p&gt;What other AI terms have you found confusing? Let me know in the comments!&lt;/p&gt;

</description>
      <category>chaicode</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Advice for Intermediate developers</title>
      <dc:creator>RAM PANDEY</dc:creator>
      <pubDate>Sun, 09 Jun 2024 15:50:55 +0000</pubDate>
      <link>https://dev.to/rampa2510/advice-for-intermediate-developers-4777</link>
      <guid>https://dev.to/rampa2510/advice-for-intermediate-developers-4777</guid>
      <description>&lt;h1&gt;
  
  
  Prologue
&lt;/h1&gt;

&lt;p&gt;I wrote &lt;a href="https://dev.to/rampa2510/3-tips-for-new-developers-49hj"&gt;this blog&lt;/a&gt; five years ago when I was a junior developer. The tips I shared back then are still rules I follow today and have become an integral part of me. I've grown a lot as a developer, so now I want to give back to the community as an intermediate developer.&lt;br&gt;
The advice mentioned here is for people who love their craft and want to get better at it, not for the sake of better compensation but for the joy of programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Love your job
&lt;/h2&gt;

&lt;p&gt;I've seen people treat programming as just a job, doing it only for the money. They program to earn a living and go about their daily lives. This lifestyle is fine, its your choice. But don't be surprised if your skills don't improve and you become stagnant. To become great at programming, you have to love your job. You spend most of your day programming at your day job, and if you don't love it, you won't take the initiative to improve your skills while working.&lt;/p&gt;

&lt;p&gt;I have a personal story to share. I once worked at a company I hated. I didn't take any initiative to improve the codebase or learn new things to enhance the application architecture. Now, I work at a job I love and treat it as my own product. This often leads me to learn new things and develop the codebase in a well-structured manner because I don't want to ruin it. If you do what you don't love, you'll do more harm than good. You can learn after work, but you would have wasted around six hours of your day and accomplished very little.&lt;/p&gt;

&lt;h2&gt;
  
  
  2) Be a generalist
&lt;/h2&gt;

&lt;p&gt;Never put yourself in a box. Don’t think of yourself as just a frontend developer or backend developer. Think of yourself as a software developer. Great developers don't limit themselves to specific technologies they focus on solving problems, not just parts of a problem. If you limit yourself to a certain stack, you won't become a great problem solver. Software development is all about problem-solving, and if you don’t understand how to build an end-to-end product, you won’t be a good problem solver.&lt;/p&gt;

&lt;p&gt;At the start of your career, you might have to choose a specific stack to prove yourself as a great software developer. But don't let that limit you. If you work at a good company, talk with a senior or other developers to gain insights into different teams and learn new things. Start taking responsibility for other parts of your company's codebase to transition into a more full-stack developer role. This way, you'll start thinking more about solving whole problems rather than just parts. If you are not welcomed to work with other stacks I would recommend working at another job. A company should never limit the learning of their engineers.&lt;/p&gt;

&lt;p&gt;So, be a generalist. Don’t limit yourself to one part of the stack. Learn to solve problems as a software developer. Generalists find it easier to be good at solving specific problems because they can pick up new technologies faster since they already have a broad understanding.&lt;/p&gt;

&lt;h2&gt;
  
  
  3) Never stop learning new tech ( Be a tinkerer )
&lt;/h2&gt;

&lt;p&gt;This is a crucial point that many developers overlook. To be a good problem solver, you must keep yourself up to date with the latest advancements in your technology. I find a lot of joy in my hobby projects, which help me develop many skills. When you tinker with new stuff, you learn a lot, and you never know when it will become useful.&lt;/p&gt;

&lt;p&gt;For example, imagine you've been tasked with creating a blogging application for your company. They want a custom solution, not something that uses Webflow and other similar services. If you've kept up with the latest advancements, you can use modern CMS tools like Supabase or Pocketbase to develop the backend quickly. It might take just 30 minutes to set up a CMS for your blogging site, saving you from creating and managing the database and backend code. Then you can focus on the frontend according to your company's needs.&lt;/p&gt;

&lt;p&gt;Here's a personal example: I’ve been learning Go for a month on the side. Recently, I had to write a cron job to update user metrics every 30 minutes. Knowing that Go is great and very fast for such tasks, I created the cron job in Go, built the binary, and scheduled a system daemon task with a timer for every 30 minutes. It works efficiently and consumes fewer resources. If I hadn't been tinkering in my spare time and only wrote code at my day job, I wouldn’t have come up with the best solution in a reasonable time. The cron job would have been written in Node, which would take more time as the user base grows.&lt;/p&gt;

&lt;p&gt;So, never stop learning and creating on the side. The best way to learn is by creating and tinkering. I’ve been learning Ruby on Rails and Go on the side, and I’ve come to appreciate the different features that various ecosystems offer. This has helped me integrate new ideas into my workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  4) Take ownership
&lt;/h2&gt;

&lt;p&gt;I recently watched a &lt;a href="https://www.youtube.com/watch?v=5i_O6NLXYsM&amp;amp;t=1586s" rel="noopener noreferrer"&gt;video&lt;/a&gt; of ThePrimagen that inspired me to write this blog. He mentioned that the best way to solve a problem or become a great software developer is to take ownership of the product. He talked about how Doom was created by just four guys who delivered such a good product because they took ownership. They knew they had no one else to rely on, so they made it their responsibility to develop the best possible software. There was no Plan B. They never felt burnout or gave up because they owned the product, not just the tasks.&lt;/p&gt;

&lt;p&gt;To improve your skills as a software developer, you need to start taking ownership of the product you are building, not just features or tasks. You will find it much more enjoyable to work on a product when you see any feature or bug as your problem to solve, not just another task for someone else. This is the best way to beat burnout. When you take ownership, you will find joy in improving and making the product more efficient.&lt;/p&gt;

&lt;p&gt;If you are working on a product, you can't blame others for any bugs that come up when users find them. You are part of the problem if things go wrong, so you have to take ownership to fix them and make a great product. Good, scalable products are built by teams, and if you don't take ownership, you are not a good team member. When you take ownership, you write the best possible code to create the best possible software, not just another software product.&lt;/p&gt;

&lt;p&gt;Like the four guys who made Doom, they put in an insane amount of time to create something that was theirs, and they never settled for just another game, they created an era-defining game. The rest, as they say, is history. The same applies to you, if you want to make the best possible software, you have to start taking ownership and think of the product as your own.&lt;/p&gt;

&lt;h1&gt;
  
  
  Epilogue
&lt;/h1&gt;

&lt;p&gt;I feel good after writing this blog and sharing my thoughts with the community. We might argue about frameworks, languages, and tools, but these debates help us improve. They push technology forward, making our community very competitive. Let's keep the passion alive!&lt;/p&gt;

</description>
      <category>software</category>
      <category>community</category>
      <category>developer</category>
      <category>career</category>
    </item>
    <item>
      <title>MongoDB Replication Why and How?</title>
      <dc:creator>RAM PANDEY</dc:creator>
      <pubDate>Sat, 16 Sep 2023 15:49:24 +0000</pubDate>
      <link>https://dev.to/rampa2510/mongodb-replication-why-and-how-53c5</link>
      <guid>https://dev.to/rampa2510/mongodb-replication-why-and-how-53c5</guid>
      <description>&lt;p&gt;Hello, fellow developers! I trust you're doing splendidly. In this week's blog, we're delving into the intriguing world of MongoDB replication—the 'why' and 'how' behind it. Let's kick things off with the fundamental question: why replication?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Why
&lt;/h2&gt;

&lt;p&gt;Imagine your database as a bustling library of books, each book representing your valuable data. In a single-library setup, you have one copy of each book stored on a single shelf. While this might seem fine, it leaves your collection vulnerable. If, heaven forbid, that one shelf were to collapse or a book went missing, you'd lose precious knowledge.&lt;/p&gt;

&lt;p&gt;Now, consider database replication as a strategy akin to having multiple libraries, each housing an identical collection of your books. This redundancy ensures that even if one library faces an issue—like a shelf collapsing (hardware failure) or a curious book thief (data corruption)—your knowledge remains intact in other libraries. This way, your data stays resilient, accessible, and safe.&lt;/p&gt;

&lt;p&gt;The pitfalls of not considering replication become evident when you rely on a single library. In case of hardware failure, your entire collection is at risk, leading to data loss and costly downtime. Without replication, scaling to meet increasing demand becomes challenging, limiting your application's potential.&lt;/p&gt;

&lt;p&gt;However, with replication, you enjoy an array of benefits. Improved data availability means your application stays up and running even in adverse conditions. Load balancing ensures efficient resource utilization, while failover mechanisms kick in when needed, ensuring uninterrupted service. Plus, you can easily scale your database to accommodate growing workloads.&lt;/p&gt;

&lt;p&gt;In essence, replication is your fail-safe mechanism, your data's guardian angel. It's not just a best practice; it's a lifeline for safeguarding your precious data, avoiding potential pitfalls, and reaping the many benefits it brings to the table. Now that we understand the vital importance of replication for your database, let's delve into the 'how' — how to create a replication set in MongoDB.&lt;/p&gt;

&lt;h2&gt;
  
  
  How a Production level setup would look
&lt;/h2&gt;

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

&lt;p&gt;Now that we've explored why replication is crucial, let's delve into how a production-level setup would appear.&lt;/p&gt;

&lt;p&gt;In the illustration above, you can observe a primary node and two distinct secondary databases. Additionally, there's an arbiter situated on its own server, tasked with monitoring all the databases within the cluster. It continuously sends out small heartbeats to ensure all the machines remain online. In the event that the primary node experiences downtime, communication with it becomes impossible. In such a scenario, the arbiter steps in and assesses the remaining servers within your cluster. Subsequently, it will arbitrarily promote one of the secondary servers to assume the role of the new primary. This mechanism ensures the continued operation of your database even in the face of primary node failures.&lt;/p&gt;

&lt;p&gt;For this demonstration, we will create a primary and a secondary node. However, if you intend to implement this replication setup in a production environment, I highly recommend following the complete setup outlined above.&lt;/p&gt;

&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Note: To follow along as we configure a replica set, it's recommended to download the latest version of MongoDB Community Edition. At the time of writing, the latest version is 7.0. For this blog, we'll use MacOS. While most commands are universal and work on both Linux and MacOS, Windows users may need to find equivalent commands.&lt;/p&gt;

&lt;p&gt;Before diving into creating a replica set configuration, let's first grasp the basics of spinning up a MongoDB database. After all, a replica set comprises multiple databases. MongoDB relies on a configuration file called &lt;code&gt;mongod.conf&lt;/code&gt;. The location of this file varies by operating system:&lt;/p&gt;

&lt;p&gt;The location of &lt;code&gt;mongod.conf&lt;/code&gt; for different OS are&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OS&lt;/th&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;td&gt;/etc/mongod.conf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MacOS&lt;/td&gt;
&lt;td&gt;/usr/local/etc/mongod.conf (on Intel processors), or /opt/homebrew/etc/mongod.conf (on Apple M1 processors)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows&lt;/td&gt;
&lt;td&gt;&amp;lt; install_directory &amp;gt;\bin\mongod.cfg&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To keep things organized and prevent unintentional changes to the default configuration, let's create new files and name it &lt;code&gt;mongod.primary.conf&lt;/code&gt; and &lt;code&gt;mongod.secondary.conf&lt;/code&gt;. This approach ensures that even if we make errors during the setup process, the default database remains unaffected.&lt;/p&gt;

&lt;p&gt;To create the configuration files, we will begin by making a copy of the default configuration:&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;sudo cp &lt;/span&gt;mongod.conf mongod.primary.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp &lt;/span&gt;mongod.conf mongod.secondary.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's edit the configuration files to customize the settings. For each file, we will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set the destination for system logs.&lt;/li&gt;
&lt;li&gt;Specify the data storage path (dbPath).&lt;/li&gt;
&lt;li&gt;Define the port on which MongoDB should listen for requests.&lt;/li&gt;
&lt;li&gt;Assign a name to the replication set.&lt;/li&gt;
&lt;li&gt;Configure the MongoDB server to run as a background process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;mongod.primary.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;systemLog&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;file&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/usr/local/var/log/mongodb/mongo.primary.log&lt;/span&gt;
  &lt;span class="na"&gt;logAppend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dbPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/usr/local/var/mongodb-primary&lt;/span&gt;
&lt;span class="na"&gt;net&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;27018&lt;/span&gt;
  &lt;span class="na"&gt;bindIp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;127.0.0.1&lt;/span&gt;
&lt;span class="na"&gt;replication&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replSetName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;demoRepl&lt;/span&gt;
&lt;span class="na"&gt;processManagement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;fork&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;mongod.secondary.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;systemLog&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;file&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/usr/local/var/log/mongodb/mongo.secondary.log&lt;/span&gt;
  &lt;span class="na"&gt;logAppend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dbPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/usr/local/var/mongodb-secondary&lt;/span&gt;
&lt;span class="na"&gt;net&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;27019&lt;/span&gt;
  &lt;span class="na"&gt;bindIp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;127.0.0.1&lt;/span&gt;
&lt;span class="na"&gt;replication&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replSetName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;demoRepl&lt;/span&gt;
&lt;span class="na"&gt;processManagement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;fork&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have added the &lt;code&gt;processManagement.fork&lt;/code&gt; option. This setting instructs the mongod server to run as a background process, allowing you to regain control of the terminal for running other commands.&lt;/p&gt;

&lt;p&gt;You should also update the dbPath with the appropriate location for your operating system. Here are the default directories where MongoDB data is typically stored:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OS&lt;/th&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;td&gt;/var/lib/mongodb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MacOS&lt;/td&gt;
&lt;td&gt;/usr/local/var/mongodb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows&lt;/td&gt;
&lt;td&gt;C:\data\db&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Please make sure to specify the dbPath according to your specific operating system.&lt;/p&gt;

&lt;p&gt;The next crucial step is to create the necessary directories for storing the database data. Failure to do so may result in issues when starting the MongoDB server. Make sure to create these directories in advance to ensure a smooth setup process.&lt;/p&gt;

&lt;p&gt;To create the necessary directories for the databases, you can use the mkdir command (for Linux and Mac). In this example, I'll create the directories in &lt;code&gt;/usr/local/var/&lt;/code&gt;, but you should adjust the paths according to your preferences.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;sudo mkdir /usr/local/var/mongodb-primary 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;sudo mkdir /usr/local/var/mongodb-secondary 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the directories in place, we're now ready to start up the databases.&lt;/p&gt;

&lt;p&gt;To start the MongoDB server, you can use the &lt;code&gt;mongod&lt;/code&gt; tool, which is included with the MongoDB installation. The command to start the server is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;sudo mongod --config &amp;lt;config_file_name&amp;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 command, you specify the config file for the server to retrieve the necessary instance details.&lt;/p&gt;

&lt;p&gt;Running this command will produce output similar to the following:&lt;/p&gt;

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

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

&lt;p&gt;Notice that MongoDB forked as a child process. If you didn't specify the fork option, you would have lost control of the terminal. You can try running it both ways to see the difference in behavior.&lt;/p&gt;

&lt;p&gt;If your setup was correct, you would be able to create both the instance without any issues.&lt;/p&gt;

&lt;p&gt;Now lets get access to our databases using the &lt;code&gt;mongosh&lt;/code&gt; tool which was shipped with the mongodb installation as well. We will write the commands in two different terminal tabs to get access to both of them at the same time&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;mongosh --port 27018
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;mongosh --port 27019
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should be able to get access and get an output similar to this&lt;/p&gt;

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

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

&lt;p&gt;Now, if you try running any command in either of them, you will encounter an error like this:&lt;/p&gt;

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

&lt;p&gt;The reason for this error is that, since we have specified the replication set name, the MongoDB instance will only be able to access the database after syncing with the other databases in the replication set. However, we haven't initialized the connection yet, so it remains in an unknown state.&lt;/p&gt;

&lt;p&gt;To resolve this, we will start by using the primary database tab and running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rs.initiate&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command will produce an output like this:&lt;/p&gt;

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

&lt;p&gt;In this step, we haven't provided any specific configuration for the replica set, which is why you'll see an info message.&lt;/p&gt;

&lt;p&gt;Now, let's add the secondary database to our replica set using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rs.add&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;servername&amp;gt;:&amp;lt;port&amp;gt;"&lt;/span&gt;&lt;span class="o"&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 shell"&gt;&lt;code&gt;rs.add&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"127.0.0.1:27019"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this command should yield an output like this:&lt;/p&gt;

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

&lt;p&gt;With this, our replication set is now complete!&lt;/p&gt;

&lt;p&gt;To check the status or obtain details about your replica set, you can use the &lt;code&gt;rs.status()&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Let's create a new database in the primary and verify if the changes are replicating in the secondary node or not.&lt;/p&gt;

&lt;p&gt;Primary Database View:&lt;/p&gt;

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

&lt;p&gt;Secondary Database View:&lt;/p&gt;

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

&lt;p&gt;As you can see, without any additional effort, the database changes from the primary have been successfully replicated in the secondary. With these steps, we have configured our very own replication set.&lt;/p&gt;

&lt;p&gt;I hope you found this tutorial informative and valuable. Please feel free to share any feedback or suggestions with me. Thank you for reading, and until next time!&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>database</category>
      <category>systemdesign</category>
      <category>learning</category>
    </item>
    <item>
      <title>Guide to building Multi-Tenant Architecture in Nodejs</title>
      <dc:creator>RAM PANDEY</dc:creator>
      <pubDate>Sun, 10 Sep 2023 18:48:09 +0000</pubDate>
      <link>https://dev.to/rampa2510/guide-to-building-multi-tenant-architecture-in-nodejs-40og</link>
      <guid>https://dev.to/rampa2510/guide-to-building-multi-tenant-architecture-in-nodejs-40og</guid>
      <description>&lt;p&gt;Greetings, fellow developers! I hope you're all doing well. Today, I'm thrilled to delve into the realm of multi-tenant architecture and share my insights and experiences from constructing a backend application that fully embraces this approach.&lt;/p&gt;

&lt;p&gt;Let's paint a vivid picture: imagine your software as a colossal apartment complex. In this virtual edifice, every user or organisation functions as a tenant, residing in one of the apartments. They peacefully coexist within the same architectural structure, which represents your software's backend. However, they each maintain their unique, private spaces — think of them as their data sanctuaries housed in separate databases. The primary objective? Safeguarding their data, ensuring its security, and enforcing strict boundaries to prevent any unauthorised peeping into their digital "apartments." It's akin to orchestrating the management of a vast, interconnected digital apartment complex!&lt;/p&gt;

&lt;p&gt;In this blog, we'll demystify the complexities of multi-tenant architecture, making it accessible even to beginners. So, let's embark on this enlightening journey together!&lt;/p&gt;

&lt;p&gt;Before we commence, I'd like to extend a special shout-out to this exceptional &lt;a href="https://medium.com/geekculture/building-a-multi-tenant-app-with-nodejs-mongodb-ec9b5be6e737" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; blog that served as a wellspring of inspiration for my exploration.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge at Hand
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Each tenant must have their dedicated database.&lt;/li&gt;
&lt;li&gt;Admin should possess the capability to deactivate specific tenants.&lt;/li&gt;
&lt;li&gt;Storing user passwords in the main database is an absolute no-go.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Of course, there were other requirements as well, but we'll keep our focus squarely on these for the scope of this blog. &lt;/p&gt;

&lt;h2&gt;
  
  
  High Level Overview
&lt;/h2&gt;

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

&lt;p&gt;As you can see, we have four clients, each with their own database. They all interact with the same backend, which performs its magic and connects them with their respective databases. To manage all of this, we need a super admin database that keeps track of all users and can store additional details you might need, such as pricing information or the modules to which a tenant has access.&lt;/p&gt;

&lt;p&gt;Now that we've set the stage, let's dive into the exciting part – the code!&lt;/p&gt;

&lt;p&gt;For this example, I'll be using Node.js, Express, and MongoDB for the database. However, you can adapt this approach to suit your tech stack. It's surprisingly straightforward once you grasp the concept.&lt;/p&gt;

&lt;p&gt;P.S - After I completed the blog I noticed that the blog got too technical and some people might not like it and would only visit to get the gist or an idea of how it works. So I have added a section at last which gives the application overview. You can use that to just get the idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Initialisation
&lt;/h3&gt;

&lt;p&gt;To kickstart our project, let's create a directory for it. I'll name it "multi-tenant," but feel free to choose a name that suits your project.&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;multi-tenant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this we initialise the npm project&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;Now, let's install the necessary third-party packages.&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 cookie-parser express jsonwebtoken lru-cache mongoose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free to initialize a Git repository as well, but for this demo, I won't cover that step.&lt;/p&gt;

&lt;p&gt;Additionally, I'll be using ES6 modules instead of CommonJS. Please bear with me, as I work on both frontend and backend, and I prefer to keep things consistent when possible. To enable ES6 modules, you can add "type": "module" in your package.json or use the .mjs file extension.&lt;/p&gt;

&lt;h3&gt;
  
  
  Directory Structure
&lt;/h3&gt;

&lt;p&gt;Before we dive into the code, let me explain how I organize my backend projects into different directories to keep the codebase organized. This structure is what we'll follow for this blog:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Controllers - Controllers: This is where API entry points reside, mainly for request validation.&lt;/li&gt;
&lt;li&gt;Services - Here, the core business logic of the backend lives. It includes data manipulation, API calls, and database query building.&lt;/li&gt;
&lt;li&gt;Repositories - These interact with the database. Services call repositories after constructing queries, and repositories handle database interactions and return results.&lt;/li&gt;
&lt;li&gt;Utils - In this directory, I store helper functions that don't interact with clients but assist the backend, such as password hashing, JWT management, etc.&lt;/li&gt;
&lt;li&gt;Middleware - This directory contains code executed before reaching our APIs. It's where we can write logic to determine the database to use and validate the tenant. This separation helps keep our main backend logic separate from connection logic.&lt;/li&gt;
&lt;li&gt;Server - This holds configuration files for our server, such as Express setup and potentially CORS configuration (not used in this demo but recommended).&lt;/li&gt;
&lt;li&gt;Routes - Code in this directory defines the routes and endpoints that clients can access.&lt;/li&gt;
&lt;li&gt;Schema - Here, we store the database schema.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
├── controllers
├── middleware
├── repositories
├── routes
├── schema
├── server
├── services
└── utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how our directory will look like.&lt;/p&gt;

&lt;p&gt;Now, keep in mind that I won't go super deep into how to separate admin and tenant logic in this demo, but you can achieve it by creating separate admin and tenant directories within all the the directories to organize the logic accordingly. For this demo, we're focusing on setting up the architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Our Server
&lt;/h3&gt;

&lt;p&gt;We'll start by creating the entry point for our server, which is the index.js file. It will initialize the Express app. The actual initialization of our Express app will be handled in the server directory, as index.js doesn't need to worry about the Express setup; its role is to require all the initialization functions, which connect to the DB, initialize middleware, set up Redis, etc.&lt;/p&gt;

&lt;p&gt;Here's the &lt;code&gt;server/express.config.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;ExpressConfig&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="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="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="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;trust proxy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&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;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;ExpressConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Now, let's use this configuration in our &lt;code&gt;index.js&lt;/code&gt;, which will bind our server to a port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ExpressConfig&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./server/express.config.js&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="nc"&gt;ExpressConfig&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;5000&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="k"&gt;async &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;`Multi Tenant Backend running 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;It's important to note that for this demo, I haven't used environment variables to define the port. However, in your production project, it's highly recommended to use environment variables. This allows you to set the &lt;code&gt;PORT&lt;/code&gt; variable and other configuration options dynamically based on your environment, making your application more flexible and secure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initial Middleware setup
&lt;/h3&gt;

&lt;p&gt;Now, let's dive into setting up the initial middleware for our backend. Currently, we'll implement the essential middleware, and we'll revisit this section when we need to code the logic for validating and determining the database connection.&lt;/p&gt;

&lt;p&gt;We start by creating the &lt;code&gt;middleware/index.js&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cors&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;cookieParser&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cookie-parser&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;function &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;Application&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cookieParser&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;For this demo, we've kept it simple. We're using cookie-parser to handle tokens as HTTP-only cookies. In production code, you can expand on this file to include additional middleware such as defining CORS policies, rate limiting, setting up request context (a file used to log the request-response cycle), and more. Feel free to customize it according to your project's specific requirements and security considerations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database schema setup
&lt;/h3&gt;

&lt;p&gt;Now, let's define the schema for our data. In this demo, I'll keep it simple, covering the basic elements, but please feel free to modify it to suit your specific requirements. It's worth noting that I'm not registering my collections with &lt;code&gt;mongoose.model&lt;/code&gt; here. I'll register them when I start working on the database connection setup. The reason behind this is to avoid registering super admin schemas for tenants and vice versa. We want to keep these schemas separate.&lt;/p&gt;

&lt;p&gt;Let's begin with the super admin collections.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tenant Collection
&lt;/h4&gt;

&lt;p&gt;The first collection I want to build is the tenant collection. In this collection, you can store metadata related to tenants, such as the modules they've purchased, user limits, and whether they are enabled or disabled. For simplicity, I'll only store the name and database URI. Here's the code for &lt;code&gt;schema/tenant.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="nx"&gt;Schema&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="s2"&gt;mongoose&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;tenantSchema&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;Schema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;dbUri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&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="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;tenantSchema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Tenant User Collection
&lt;/h4&gt;

&lt;p&gt;The second super admin collection stores all the users our application has, regardless of their tenant. Again, for simplicity, I'll keep it basic. You can extend it to include fields like user roles or whether they are tenant administrators. Here's the code for &lt;code&gt;schema/tenantUser.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;Types&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="s2"&gt;mongoose&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;tenantUserSchema&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;Schema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
       &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tenants&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="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;tenantUserSchema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the tenants Database will have -&lt;/p&gt;

&lt;h4&gt;
  
  
  Users Collection
&lt;/h4&gt;

&lt;p&gt;The third collection is a tenant collection. This will store data related to the users of that specific tenant. I've kept it basic for the demo, but you can add relevant fields to your schema as needed. Here's the code for &lt;code&gt;schema/users.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Schema&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="s2"&gt;mongoose&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;usersSchema&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;Schema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;usersSchema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these database schema definitions in place, you now have a general idea of the project structure and how the data is organized. Feel free to adapt and extend these schemas to match your project's specific requirements. &lt;/p&gt;

&lt;h3&gt;
  
  
  Repositories
&lt;/h3&gt;

&lt;p&gt;In this section, we'll define simple functions that take a query and perform database operations using it. Note that the first parameter for these functions will always be a database connection object. Since we're dealing with multiple database connections in a multi-tenant setup, we need to provide the appropriate database connection to the repository so it can perform operations on the correct database.&lt;/p&gt;

&lt;p&gt;Let's start with the &lt;code&gt;repositories/tenant.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mongoose&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;mainSchemaName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tenants&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;getTenantsRepo&lt;/span&gt; &lt;span class="o"&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;adminDbConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;findQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;selectQuery&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="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;data&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;adminDbConnection&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lean&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;data&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;getATenantRepo&lt;/span&gt; &lt;span class="o"&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;adminDbConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;findQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;selectQuery&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="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;data&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;adminDbConnection&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lean&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;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// This function is part of a service&lt;/span&gt;
&lt;span class="c1"&gt;// that involves many database calls, &lt;/span&gt;
&lt;span class="c1"&gt;// so we'll use transactions here.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addATenantRepo&lt;/span&gt; &lt;span class="o"&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;adminDbConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;tenantData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;sessionOption&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;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;sessionOption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;session&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;data&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;adminDbConnection&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;tenantData&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;sessionOption&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;data&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="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateATenant&lt;/span&gt; &lt;span class="o"&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;adminDbConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;findQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;updateQuery&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="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;data&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;adminDbConnection&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateQuery&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;data&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getTenantsRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getATenantRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addATenantRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateATenant&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's move on to the &lt;code&gt;repositories/tenantUser.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mainSchemaName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tenantusers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// This function is part of a service &lt;/span&gt;
&lt;span class="c1"&gt;// with transactions.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addATenantUserRepo&lt;/span&gt; &lt;span class="o"&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;dbConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;sessionOption&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;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;sessionOption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;session&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;data&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;dbConn&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;sessionOption&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;data&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="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getATenantUserRepo&lt;/span&gt; &lt;span class="o"&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;dbConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;selectQuery&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="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;data&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;dbConn&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lean&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;data&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;updateATenantUserRepo&lt;/span&gt; &lt;span class="o"&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;dbConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;updateQuery&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;data&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;dbConn&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateQuery&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;data&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addATenantUserRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getATenantUserRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateATenantUserRepo&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, we have the &lt;code&gt;repositories/users.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mainSchemaName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;// This function is part of the service &lt;/span&gt;
&lt;span class="c1"&gt;// with transactions.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addAUserRepo&lt;/span&gt; &lt;span class="o"&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;dbConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;sessionOption&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;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;sessionOption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;session&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;data&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;dbConn&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;sessionOption&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;data&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="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getAUserRepo&lt;/span&gt; &lt;span class="o"&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;dbConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;findQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;selectQuery&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="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;data&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;dbConn&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lean&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;data&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;updateUserRepo&lt;/span&gt; &lt;span class="o"&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;dbConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;updateQuery&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;data&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;dbConn&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateQuery&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;data&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;getUsersRepo&lt;/span&gt; &lt;span class="o"&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;dbConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;findQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;selectQuery&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="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;data&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;dbConn&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainSchemaName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;findQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lean&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;data&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;addAUserRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getAUserRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;updateUserRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getUsersRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Main connection setup
&lt;/h3&gt;

&lt;p&gt;In this section, we will focus on setting up the logic for managing all the database connections and utilizing an optimal database structure, such as an LRU (Least Recently Used) cache, to efficiently manage these connections. While we're defining both initialization functions for the admin and tenant connections here, you should consider separating the logic for better organization. Additionally, note that we register the models here on the database object.&lt;/p&gt;

&lt;p&gt;Lets start with the &lt;code&gt;utils/initDBConnection.js&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Connection&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="s2"&gt;mongoose&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;TenantSchema&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../schema/tenant.js&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;TenantUserSchema&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../schema/tenantUser.js&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;UserSchema&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../schema/user.js&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;clientOption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;socketTimeoutMS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;useNewUrlParser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;useUnifiedTopology&lt;/span&gt;&lt;span class="p"&gt;:&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="c1"&gt;// Log MongoDB queries&lt;/span&gt;
&lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;debug&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&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;initAdminDbConnection&lt;/span&gt; &lt;span class="o"&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;DB_URL&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;try&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DB_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clientOption&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&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;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="s2"&gt;Admin db error: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;open&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="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="s2"&gt;Admin client MongoDB Connection 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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tenants&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TenantSchema&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tenantusers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;TenantUserSchema&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;db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;error&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;const&lt;/span&gt; &lt;span class="nx"&gt;initTenantDBConnection&lt;/span&gt; &lt;span class="o"&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;DB_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;dbName&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;try&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DB_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clientOption&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&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;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;`Tenant &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; db error: `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;open&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="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;`Tenant connection for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; MongoDB Connection ok!`&lt;/span&gt;
      &lt;span class="p"&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserSchema&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;db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;error&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;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;initAdminDbConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initTenantDBConnection&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Now, let's define the code for the LRU cache manager in the &lt;code&gt;utils/lruCacheManager.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LRUCache&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="s2"&gt;lru-cache&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Connection&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="s2"&gt;mongoose&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;cacheOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;maxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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;connectionCache&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;LRUCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheOptions&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;setCacheConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dbConn&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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="s2"&gt;Setting connection cache for &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;connectionCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dbConn&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;getCacheConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tenantId&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;return&lt;/span&gt; &lt;span class="nx"&gt;connectionCache&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="nx"&gt;tenantId&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;getCacheValuesArr&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;connectionCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setCacheConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getCacheConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getCacheValuesArr&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Now, let's code the file that is the heart of the application, the connection manager file! This file contains the logic for initializing the database and managing the collections so that our application can use them. Here is the code for &lt;code&gt;utils/connectionManager.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mongoose&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;initAdminDbConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initTenantDBConnection&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="s2"&gt;./initDBConnection.js&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getATenantRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getTenantsRepo&lt;/span&gt;&lt;span class="p"&gt;,&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="s2"&gt;../repositories/tenant.js&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getCacheConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getCacheValuesArr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;setCacheConnection&lt;/span&gt;&lt;span class="p"&gt;,&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="s2"&gt;./lruCacheManager.js&lt;/span&gt;&lt;span class="dl"&gt;"&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;adminDbConnection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// This function will be called at the start&lt;/span&gt;
&lt;span class="c1"&gt;// of our server. Its purpose is to initialize the admin database&lt;/span&gt;
&lt;span class="c1"&gt;// and the database connections for all of the tenants.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connectAllDb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;ADMIN_DB_URI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`your admin db uri`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;adminDbConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;initAdminDbConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ADMIN_DB_URI&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;allTenants&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTenantsRepo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;adminDbConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;dbUri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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="mi"&gt;1&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;const&lt;/span&gt; &lt;span class="nx"&gt;tenant&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;allTenants&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;tenantConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;initTenantDBConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;tenant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dbUri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;tenant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;setCacheConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tenant&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="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;tenantConnection&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getConnectionForTenant&lt;/span&gt; &lt;span class="o"&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;tenantId&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;`Getting connection from cache for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tenantId&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCacheConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tenantId&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;connection&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Connection cache miss for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tenantId&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tenantData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getATenantRepo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;adminDbConnection&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="nx"&gt;tenantId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;dbUri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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;tenantData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;initTenantDBConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;tenantData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dbUri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;tenantData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;connection&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;null&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="s2"&gt;Connection cache added for &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tenantData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="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="s2"&gt;No connection data for tenant with ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;tenantId&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;null&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;return&lt;/span&gt; &lt;span class="nx"&gt;connection&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getAdminConnection&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="s2"&gt;Getting adminDbConnection&lt;/span&gt;&lt;span class="dl"&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;adminDbConnection&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;gracefulShutdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="s2"&gt;Closing all database connections...&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;connectionArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCacheValuesArr&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Close all tenant database connections from the cache&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;const&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;connectionArr&lt;/span&gt;&lt;span class="p"&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;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&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="s2"&gt;Tenant database connection closed.&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="c1"&gt;// Close the admin database connection if it exists&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;adminDbConnection&lt;/span&gt;&lt;span class="p"&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;adminDbConnection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&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="s2"&gt;Admin database connection closed.&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;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="s2"&gt;All database connections closed. Yay!&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isShutdownInProgress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Listen for termination signals&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SIGINT&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;SIGTERM&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;SIGQUIT&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;SIGUSR2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;signal&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signal&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="o"&gt;=&amp;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;isShutdownInProgress&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Received &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, gracefully shutting down...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;isShutdownInProgress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;gracefulShutdown&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&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="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Hash!!! that concludes the major part of our application. I hope you understand the code its not much just some functions to manage the db connections but it is still the heart of our application. &lt;/p&gt;

&lt;p&gt;Lets define some util functions that will help us later in our services. We can name this file as the misc.js which contains miscellaneous functions so here is the code for &lt;code&gt;utils/misc.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jsonwebtoken&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;signJWT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;return&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;random secret&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;verifyJWT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;payload&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;return&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;random secret&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="c1"&gt;// define in your env file&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saltRounds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;generateHash&lt;/span&gt; &lt;span class="o"&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;input&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;try&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;hash&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;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saltRounds&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;hash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error generating hash:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&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;const&lt;/span&gt; &lt;span class="nx"&gt;comparePassword&lt;/span&gt; &lt;span class="o"&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;plainPassword&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hash&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;try&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;match&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;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plainPassword&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hash&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;match&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error comparing password:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&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;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;signJWT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;verifyJWT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;generateHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;comparePassword&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Services
&lt;/h3&gt;

&lt;p&gt;In this section, we'll dive into the core business logic of our application.&lt;/p&gt;

&lt;p&gt;So lets start with the most intense service file! The &lt;code&gt;services/tenant.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mongoose&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;addATenantRepo&lt;/span&gt;&lt;span class="p"&gt;,&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="s2"&gt;../repositories/tenant.js&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addATenantUserRepo&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="s2"&gt;../repositories/tenantUser.js&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setCacheConnection&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="s2"&gt;../utils/lruCacheManager.js&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addAUserRepo&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="s2"&gt;../repositories/user.js&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;initAdminDbConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initTenantDBConnection&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="s2"&gt;../utils/initDBConnection.js&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;addATenantService&lt;/span&gt; &lt;span class="o"&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;dbConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;tenantData&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;session&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;dbConn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startSession&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startTransaction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addATenantRepo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;dbConn&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;tenantData&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nx"&gt;session&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;userData&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;data&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="nx"&gt;userData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addATenantUserRepo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;dbConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&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="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tenantData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nx"&gt;session&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;tenantDbConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;initTenantDBConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dbUri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addAUserRepo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;tenantDbConnection&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="nx"&gt;userData&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="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tenantData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nx"&gt;session&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;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commitTransaction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endSession&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="nf"&gt;setCacheConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;tenantDbConnection&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="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Tenant added successfully`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;responseObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&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="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userData&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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&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;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abortTransaction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endSession&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&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;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addATenantService&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The addATenantService function handles the process of adding a new tenant to the system. It follows these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adds tenant data to the super admin tenant collection.&lt;/li&gt;
&lt;li&gt;Adds user details to the super admin tenant users collection.&lt;/li&gt;
&lt;li&gt;Links the user to the tenant in the tenant users collection, maintaining consistency between the super admin and tenant databases.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, let's move on to the &lt;code&gt;services/auth.js&lt;/code&gt; file, which contains authentication-related logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;signJWT&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="s2"&gt;../utils/misc.js&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;loginService&lt;/span&gt; &lt;span class="o"&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;userData&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;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;userData&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tenantId&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="na"&gt;success&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;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`No user with the given credentials`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;responseObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;incorrectField&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&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="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Do some password matching&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signJWT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userData&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="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Logged In Successfully`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;responseObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userData&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="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The loginService function handles user login and generates an access token, which is crucial for our application as it contains the userId and tenantId. This token will be used to verify requests and determine the appropriate database connection based on the tenantId. For this demo I didn't write the code to match the passwords but you should write your own logic based on your needs.&lt;/p&gt;

&lt;p&gt;This concludes our Services section. Now lets move on to the Controllers and Route section. &lt;/p&gt;

&lt;h3&gt;
  
  
  Controllers &amp;amp; Routes
&lt;/h3&gt;

&lt;p&gt;I've covered the Services section, and now let's dive into Controllers and Routes. In this section, I'll provide you with the necessary code for setting up controllers and routes. I won't delve into detailed explanations, as the code is straightforward. However, it's essential to organize your code effectively, so I'll provide a basic structure.&lt;/p&gt;

&lt;p&gt;So here is our &lt;code&gt;controllers/index.js&lt;/code&gt; file code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;loginService&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="s2"&gt;../services/auth.js&lt;/span&gt;&lt;span class="dl"&gt;"&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;addATenantService&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="s2"&gt;../services/tenant.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loginController&lt;/span&gt; &lt;span class="o"&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;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serviceFnResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loginService&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;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceFnResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;serviceFnResponse&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addATenantController&lt;/span&gt; &lt;span class="o"&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;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serviceFnResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addATenantService&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;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceFnResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;serviceFnResponse&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;In these controllers, you should add code to validate the request body, ensuring data integrity and security. Proper input validation is a crucial step in building a robust application.&lt;/p&gt;

&lt;p&gt;Now, let's define your application's routes in the &lt;code&gt;routes/index.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&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;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&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;loginController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addATenantController&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="s2"&gt;../controllers/index.js&lt;/span&gt;&lt;span class="dl"&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="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;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;addATenantController&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="s2"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;loginController&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;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code creates an Express router and defines your application's routes. In a real-world scenario, you would likely have more routes, each mapped to specific controllers. For maintainability, consider organizing your routes into separate files, one per resource or feature.&lt;/p&gt;

&lt;p&gt;By structuring your code this way, you maintain a clean and organized project, making it easier to add new features or extend existing ones in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Middleware
&lt;/h3&gt;

&lt;p&gt;Now, let's dive into the engine of our application – the middleware. This code will handle the heavy lifting, such as deciding the database connection and tenant for each request. We'll start with the &lt;code&gt;middleware/databaseResolver.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getConnectionForTenant&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="s2"&gt;../utils/connectionManager.js&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;verifyJWT&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="s2"&gt;../utils/misc.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;databaseResolver&lt;/span&gt; &lt;span class="o"&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;_&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="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;urlArr&lt;/span&gt; &lt;span class="o"&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;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Skip database resolution for login route&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;urlArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;next&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;token&lt;/span&gt; &lt;span class="o"&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;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Handle the logic for null checking and authorization&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payloadData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verifyJWT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Handle the expiry logic, etc.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dbConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getConnectionForTenant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Here, we are directly populating the req object, but you can use&lt;/span&gt;
  &lt;span class="c1"&gt;// custom context managers in your application&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;dbConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dbConnection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;next&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've defined the basic middleware logic that resolves the appropriate database connection based on the request's tenant information. The middleware also skips this process for the login route.&lt;/p&gt;

&lt;p&gt;Next, let's configure the middleware to be used in our application. Create a new file called &lt;code&gt;server/middleware.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;databaseResolver&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="s2"&gt;../middleware/databaseResolver.js&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&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;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="nx"&gt;databaseResolver&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;You might be wondering why we use a separate file for middleware when the code is relatively short. However, in a production-level application, you'll likely have more complex middleware requirements, such as request sanitization, logging, and more. Having a separate middleware configuration file allows you to manage and organize these requirements efficiently.&lt;br&gt;
Exmaple - santizing middleware for requests, Logging middleware, etc.&lt;/p&gt;

&lt;p&gt;This file sets up your application's routes, and in a real-world scenario, you'd have multiple routes organized by resource or feature.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;server/route.config.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;routes/index.js&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&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;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;/api&lt;/span&gt;&lt;span class="dl"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now all you need to do is just require all the config in your index.js file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ExpressConfig from "./server/express.config.js";
import MiddlewareConfig from "./server/middleware.config.js";
import RouteConfig from "./server/route.config.js";

const app = ExpressConfig();

MiddlewareConfig(app)
RouteConfig(app)

const PORT = 5000;

app.listen(PORT, async () =&amp;gt; {
  console.log(`Multi Tenant Backend running on port ${PORT}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By structuring your code in this way, you maintain a clean and organized index.js file, making it easier to understand and extend your application as it grows.&lt;/p&gt;

&lt;p&gt;And we're done! Congratulations on building the foundation for your own multi-tenant application. This powerful structure can be used as a base for creating complex Software as a Service (SaaS) applications. If you feel that the technical details have become a bit overwhelming, don't worry. Let's provide an overview using a diagram to visualize how the application works, giving us a refresher on all the moving parts in our application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application Overview
&lt;/h3&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Client Request: When a user interacts with your platform, like logging in or accessing data, their request is sent to your server. This request comes with a special key called a JSON Web Token (JWT), like a secret passcode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Middleware: The request first enters a checking point called Middleware. It's like a bouncer at a club. If the request is about logging in, it gets a quick pass. Otherwise, it moves on to the next step.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database Resolver: Here comes the real magic. The Database Resolver looks at the JWT passcode and figures out which company (tenant) the user belongs to. It's like sorting mail to different mailboxes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database Connection: Once the Resolver knows which tenant it is, it opens the right door – the tenant's database. It's as if each tenant has their own room in a huge library, and only they can access their own books.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Controller: With the right room (database) open, the Controller takes over. It's like a librarian who helps you find the book you need. The Controller figures out what the user wants to do and fetches the information from the correct room (database).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Services: Inside the Controller, special helpers called Services do the hard work. They carry out tasks like checking if the user's password is correct or fetching data. These Services are like expert librarians who know where every book is kept.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database Interaction: The Services talk to the database, ask it questions, and get answers. For example, they might ask, "Is this the right password?" or "Give me the data for this user." Each tenant's data is kept separate, so there's no mix-up.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response Generation: Once the Services have all the answers, they create a response. It's like putting together a report with all the necessary information, and it includes a message like "Success!" or "Sorry, that's not right."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Controller Response: The Controller gets this report and prepares it for delivery. It's like putting it in an envelope with the user's address on it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client Response: Finally, the response is sent back to the user's device. It's like getting the report in the mail. The user sees the message and any data they requested, and they can continue using your platform.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, in simple terms, your multi-tenant application is like a giant library with many rooms (databases). When a user asks for something, the application makes sure they go to the right room to get the right information. This way, each tenant's data stays private and secure, just like different books in different rooms of the library.&lt;/p&gt;

&lt;p&gt;This system is great for running a cloud service where each tenant gets their own space while sharing the same platform.&lt;/p&gt;

&lt;p&gt;If you have any further questions or need additional clarification on specific aspects of the application, please feel free to ask! Also if you have any suggestions for improvement please do let me know I would love to hear it.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>node</category>
      <category>architecture</category>
      <category>learning</category>
    </item>
    <item>
      <title>An advanced setup for Travis CI</title>
      <dc:creator>RAM PANDEY</dc:creator>
      <pubDate>Fri, 31 May 2019 16:08:57 +0000</pubDate>
      <link>https://dev.to/rampa2510/an-advanced-setup-for-travis-ci-3i1d</link>
      <guid>https://dev.to/rampa2510/an-advanced-setup-for-travis-ci-3i1d</guid>
      <description>&lt;p&gt;In this blog post, I will guide you through the basics of the YAML file and then we will write a sample .travis.yml file which I try to make as general as possible so that you can use Travis CI more efficiently. Also, this blog post is for those people who are familiar with the concept of CI/CD and testing.&lt;/p&gt;

&lt;h2&gt;What is YAML?&lt;/h2&gt;

&lt;p&gt;YAML is a &lt;a href="https://en.wikipedia.org/wiki/Recursive_acronym" rel="noopener noreferrer"&gt;recursive acronym&lt;/a&gt; for “YAML Ain’t markup language”. Like JSON it is a data serialization language( i.e it can be used to store or transmit data across networks)&lt;/p&gt;

&lt;h2&gt;Some differences between YAML and JSON&lt;/h2&gt;

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

&lt;h2&gt;YAML syntax&lt;/h2&gt;

&lt;p&gt;I will cover some basic syntax that will get you started but if you would like to learn more, refer this &lt;a href="https://yaml.org/refcard.html" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;The basic syntax of YAML is &lt;/h3&gt;

&lt;p&gt;Key value pairs are separated using &lt;b&gt;":"&lt;/b&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;key: value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can comment using  &lt;b&gt;"#"&lt;/b&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# this is a comment in YAML
key: value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This knowledge is enough for our example. Now let us start with our .travis.yml file &lt;/p&gt;

&lt;h2&gt;The Travis config file&lt;/h2&gt;

&lt;p&gt;Please keep a note on this as YAML files have strict rules for indentation.&lt;/p&gt;

&lt;h3&gt;The programming tool &lt;/h3&gt;

&lt;p&gt;We start configuring our .travis.yml file with the language we will be using. For example, I will be creating this Travis file for my MERN stack app so I will choose my language as nodejs for testing my backend code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;language: node_js
node_js:
  - "11"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now here we tell the Travis CI that we want our environment to be nodejs we also specify the specific version of it. I used v11 you can use any version you want, you can test for multiple version by mentioning them below like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;language: node_js
node_js:
  - "11"
  - "12"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also test this for the current stable version of nodejs like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;language: node_js
node_js:
  - "stable"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;The Build Environment&lt;/h3&gt;

&lt;p&gt;We can specify the distro/OS/Build environment we would like Travis to execute our tests in. I would recommend using trusty as this distro is lightweight and more reliable. Although this is the default distro set by Travis CI, I will show you the config so that you can use any distro you want and is offered by Travis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dist: trusty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other distros offered by Travis are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu Xenial 16.04&lt;/li&gt;
&lt;li&gt;Ubuntu Precise 12.04&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Services&lt;/h3&gt;

&lt;p&gt;Many times we have various services interacting with our project. We need to include them to completely test our projects. One option you can choose is to integrate an online set up of the services but that would increase the time taken by the tests plus if the service is paid you will have to pay the extra cost for every request to your service. So Travis ci provides a solution for this by providing you the option to install the service you need with the build and configure it according to your needs.&lt;br&gt;
There are many services we can configure but this post is not about it so &lt;br&gt;
I will show you how to configure MongoDB for CI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services: mongodb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have to use the key &lt;code&gt;services&lt;/code&gt; for any service you want to tell Travis to install the dependencies. Now to configure it you can do it the same way you do locally eg-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mongodb://localhost:27017/mydb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;MongoClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&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;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;db&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;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&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="s2"&gt;Database created!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&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;that's it you have to connect to the port no 27017 on localhost. Just follow the same default connection instruction for the service you would like to connect. You can &lt;a href="https://docs.travis-ci.com/user/database-setup/" rel="noopener noreferrer"&gt;look up here&lt;/a&gt; for other services.&lt;/p&gt;

&lt;h3&gt;Environment variables&lt;/h3&gt;

&lt;p&gt;You can set up the environment variables in which you would like to test your project using the &lt;code&gt;env&lt;/code&gt; key eg -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;env:
  - NODE_ENV=ci PORT=3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;cache&lt;/h3&gt;

&lt;p&gt;You can cache directories in your build so that you do not have to download it on every build as that would cost you time so you can specify the directories you want to cache using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cache:
  directories:
    - node_modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I would like to cache my node_modules directory for every build so I don't have to download it on every build and when I add or delete a node_module Travis would just compare the package.json and make the necessary changes and cache it again&lt;/p&gt;

&lt;h3&gt;Scripts&lt;/h3&gt;

&lt;p&gt;There are various dependencies that you would like to be installed before or after the configuration of Travis CI. Or you may need to run various scripts before the build starts executing your tests. You can install or run them by using the keyword &lt;code&gt;before_install&lt;/code&gt; to run commands before execution and &lt;code&gt;install&lt;/code&gt; to install the dependencies after the Travis finishes to configure the build&lt;br&gt;
eg -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before_install:
  - sudo apt-get install -y libxml2-dev
install:
  - npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So here before installing dependencies, I would like to add a dev library and after that, I would like to run the script to install dependencies for my project.&lt;/p&gt;

&lt;p&gt;Also, you can run various scripts during the execution of the tests with the &lt;code&gt;script&lt;/code&gt; keyword eg -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script:
  - npm run start 
  - npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So these are some advanced setup you can configure Travis with to make your life easy and use CI efficiently.&lt;/p&gt;

&lt;p&gt;I would love to hear some more advanced setup from you guys that you use or your feedback for this blog I would appreciate it. Thanks for reading and I would love to hear if I was able to impart new knowledge in you through this blog post.&lt;/p&gt;

&lt;p&gt;You can connect with me here at &lt;a href="https://twitter.com/ram2510_" rel="noopener noreferrer"&gt;twitter  &lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/ram2510/" rel="noopener noreferrer"&gt;LinkedIn.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live by the name of &lt;a href="https://www.google.com/search?q=ram2510" rel="noopener noreferrer"&gt;@ram2510&lt;/a&gt; on the internet&lt;/p&gt;

</description>
      <category>git</category>
      <category>ci</category>
      <category>devops</category>
      <category>testing</category>
    </item>
    <item>
      <title>How to automate your Git workflow</title>
      <dc:creator>RAM PANDEY</dc:creator>
      <pubDate>Wed, 22 May 2019 12:36:51 +0000</pubDate>
      <link>https://dev.to/rampa2510/how-to-automate-your-git-workflow-ilh</link>
      <guid>https://dev.to/rampa2510/how-to-automate-your-git-workflow-ilh</guid>
      <description>&lt;h1&gt;GITESY&lt;/h1&gt;

&lt;p&gt;A node js based cli that can automate your git workflow!!&lt;/p&gt;

&lt;center&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkiyjjf11n7sq1q4kfnel.png" width="400" height="72"&gt;
&lt;/center&gt;

&lt;p&gt;Gone are the days when you had to manually create the git repo both locally and remotely.&lt;/p&gt;

&lt;p&gt;Now you can create the repo both locally and remotely in 3-4 clicks using &lt;b&gt;"gitesy"&lt;/b&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Type this in your command prompt/terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i gitesy -g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;please note - Install this as a global package otherwise this may not work as expected&lt;/p&gt;




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

&lt;h3&gt;
  
  
  Create a new repo
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To create a local and remote repo use gitesy -n command with the name of the repo
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  gitesy -n test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;After which if you are using this for the first time you will see a prompt for entering your credentials like this
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7iuy5c2sgbb0r0em0d2x.png" width="796" height="59"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enter them and then you will get prompts asking details of the repo fill them and then it will automatically create the repo. Then you will get the message and start working on the project !!!!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are not using this for the first time you will see a prompt asking whether gitesy can use creds you entered previously
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgpz7871kp5p2ec0dn151.gif" width="859" height="493"&gt;
It's very easy to create a new repo and start coding. I also added the none option too, just for creating an empty git repo both locally and remotely.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Add a new template
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To Add a template create a template add the features and then use this command from the same directory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  gitesy -a &amp;lt;nameOfTheTemplate&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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




&lt;h2&gt;
  
  
  Epilogue
&lt;/h2&gt;

&lt;p&gt;You can contribute to this project &lt;a href="https://github.com/ram2510/gitesy" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Things you can do &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fix typos&lt;/li&gt;
&lt;li&gt;add more general templates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please give me your suggestions they are valuable to me.&lt;/p&gt;

&lt;p&gt;Visit the npm page for gitesy &lt;a href="https://www.npmjs.com/package/gitesy" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you like this npm package please share it so that we can make this a better package with suggestions. Thank you !!!!&lt;/p&gt;

&lt;p&gt;You can connect with me here at &lt;a href="https://twitter.com/ram2510_" rel="noopener noreferrer"&gt;twitter  &lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/ram2510/" rel="noopener noreferrer"&gt;LinkedIn.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>npm</category>
      <category>node</category>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>3 Tips for new developers</title>
      <dc:creator>RAM PANDEY</dc:creator>
      <pubDate>Thu, 16 May 2019 09:02:28 +0000</pubDate>
      <link>https://dev.to/rampa2510/3-tips-for-new-developers-49hj</link>
      <guid>https://dev.to/rampa2510/3-tips-for-new-developers-49hj</guid>
      <description>&lt;h2&gt;Prolouge&lt;/h2&gt;

&lt;p&gt;I know that there are many articles on the internet where devs share their experiences and you might be thinking why should I read them but from my personal experience I find these posts useful as I get to learn something new in every post &lt;/p&gt;

&lt;p&gt;In this blog, I highlight Some mistakes that I did and have seen others make so that you do not make them or if you have already committed those mistake you recognise it and try to rectify them.&lt;/p&gt;

&lt;p&gt;I am a self-taught web developer who had no mentor or a person that I can fall back to if I needed help. I have been working as a web developer for 6 months and here are the 3 tips I wish someone told me when I started my career.&lt;/p&gt;

&lt;h2&gt;1) Be curious &lt;/h2&gt;

&lt;p&gt;I have seen many of my classmates say that they have &lt;b&gt;"learned"&lt;/b&gt; so and so programming language by attending so and so Bootcamp or taking classes online. This is a very bad sign, you just &lt;b&gt;know&lt;/b&gt; how to use this language you cannot master a programming language in 12 weeks time. But the main problem here is it kills your hunger to learn more. Remember When you started the class you were so hungry and happy to learn the language but when you complete the class and you say that you have mastered it you instantly kill that hunger. You have just learned a part of that language, you should not stop now, always try to keep learning new parts of that language. I am in no way saying that you should not take pride or enjoy the sense of accomplishment of completing the course but don't let that pride kill your hunger. Always be curious to learn new things it is a very vast field there is always something new to learn.&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;Stay Hungry Stay Foolish.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;cite&gt;– Steve Jobs&lt;/cite&gt;&lt;/p&gt;

&lt;h2&gt;2) Don't follow the trend &lt;/h2&gt;

&lt;p&gt;Here I would like to point out the mistake that I made when I first started out programming I was riding the bandwagon of hype. I wanted to do machine learning but when someone asked me why? I would say because that's the future, not because I like it or something and guess what I was never successful in my pursuit of becoming an ml engineer, as I didn't have passion for the field. I was demotivated by this. Due to which I always procrastinated and my tasks kept on piling. Then I started HTML, CSS JavaScript and &lt;i&gt;oh boy!&lt;/i&gt; it was love at first sight. I became passionate about this field and wanted to learn every new technology here. I never needed motivation again. I was enjoying every bit of it and I still do, I hope this continues. Again now I see many of my classmates riding the hypewave as when I ask them why you want to learn this technology? I get an answer stating that this will make me more money. I am not saying that you shouldn't try out the technology but first ask why do you want to. &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;The only way to do great work is to love what you do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;cite&gt;– Steve Jobs&lt;/cite&gt;&lt;/p&gt;

&lt;h2&gt;3) Don't Be disheartened by errors &lt;/h2&gt;

&lt;p&gt;While Developing new software or upgrading old ones you will definitely get many errors. Some errors might even take months to patch. Some errors will be a quick fix but you should never give up on that project just because you couldn't solve that error. There is a huge community of programmers out there that are willing to help you. You just need to ask. So the next time you encounter an "not fixable" bug or error don't give up, ask for help there are many great forums on the internet like StackOverflow where people are always willing to help. You just need to ask. &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;The only Mistake you can make is not asking for help&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;cite&gt;– Sandeep Jauhar &lt;/cite&gt;&lt;/p&gt;

&lt;h2&gt;Other mentionable tips &lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;1) Always be humble&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2) Always commit your changes! 😊&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;3) Develop soft skills &lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Epilouge&lt;/h2&gt;

&lt;p&gt;This is my first blog post ever and I had planned that I wanted to write a blog that would help the community. If you liked the blog or would like to share your own tips or if you have any suggestions for me please share your views in the comment box down below. I would really appreciate It. Thank you for reading!!!&lt;/p&gt;

&lt;p&gt;You can connect with me here or at &lt;a href="https://twitter.com/ram2510_"&gt;twitter , &lt;/a&gt; &lt;a href="https://www.linkedin.com/in/ram2510/"&gt;LinkedIn.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>developer</category>
      <category>webdeveloper</category>
      <category>life</category>
      <category>experience</category>
    </item>
  </channel>
</rss>
