<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Abdul Basit Muhyideen</title>
    <description>The latest articles on Forem by Abdul Basit Muhyideen (@kolardev).</description>
    <link>https://forem.com/kolardev</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%2F3513118%2F26bebcb7-da5c-4d3e-a752-7c78683bc839.jpg</url>
      <title>Forem: Abdul Basit Muhyideen</title>
      <link>https://forem.com/kolardev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kolardev"/>
    <language>en</language>
    <item>
      <title>🎭 Designing a User Model for Multiple Roles (Without Losing Your Mind)</title>
      <dc:creator>Abdul Basit Muhyideen</dc:creator>
      <pubDate>Sun, 26 Oct 2025 21:57:12 +0000</pubDate>
      <link>https://forem.com/kolardev/designing-a-user-model-for-multiple-roles-without-losing-your-mind-4boh</link>
      <guid>https://forem.com/kolardev/designing-a-user-model-for-multiple-roles-without-losing-your-mind-4boh</guid>
      <description>&lt;p&gt;You know that moment when your app suddenly needs &lt;em&gt;more&lt;/em&gt; kinds of users?&lt;/p&gt;

&lt;p&gt;You start with a simple &lt;code&gt;User&lt;/code&gt; model — just &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt;.&lt;br&gt;
Life is peaceful. Everything makes sense.&lt;/p&gt;

&lt;p&gt;Then your PM drops the bomb:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We need admins, vendors, and customers.&lt;br&gt;
And some users can be all three.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now you’re staring at your schema thinking,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Maybe it’s time to switch careers.” 😅&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don’t panic — we’ve all been there.&lt;/p&gt;

&lt;p&gt;In this post, we’ll design a &lt;strong&gt;clean, scalable, multi-role user system&lt;/strong&gt; — the kind that won’t collapse the moment your startup adds a new user type.&lt;/p&gt;

&lt;p&gt;We’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;bad ideas&lt;/strong&gt; (you’ve probably written before)&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;better ideas&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;And finally, the &lt;strong&gt;best structure&lt;/strong&gt; — one user table + separate profile tables.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧱 1. The One-Table Disaster
&lt;/h2&gt;

&lt;p&gt;Most apps start like this:&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="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vendor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="nx"&gt;storeName&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;walletBalance&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It &lt;em&gt;looks&lt;/em&gt; fine — until reality hits.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customers don’t have &lt;code&gt;storeName&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Vendors don’t have &lt;code&gt;walletBalance&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Admins don’t need half the columns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now your table looks like a junk drawer full of nullable fields.&lt;br&gt;
Welcome to the &lt;strong&gt;God Table Anti-Pattern&lt;/strong&gt; — one table trying to be everything, and doing nothing well.&lt;/p&gt;


&lt;h2&gt;
  
  
  🪓 2. The “Split Everything” Overcorrection
&lt;/h2&gt;

&lt;p&gt;Then comes the overcorrection phase:&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="nx"&gt;Admin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&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="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;permissions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;Vendor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&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="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;storeName&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;Customer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&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="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;walletBalance&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks cleaner, right?&lt;br&gt;
Until you realize you just broke your system in three places.&lt;/p&gt;

&lt;p&gt;Now you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3 login routes&lt;/li&gt;
&lt;li&gt;3 sets of authentication logic&lt;/li&gt;
&lt;li&gt;3 password reset flows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And worst of all:&lt;br&gt;
A user can’t be both a &lt;strong&gt;vendor&lt;/strong&gt; and a &lt;strong&gt;customer&lt;/strong&gt; without two separate accounts. 🤦‍♂️&lt;/p&gt;

&lt;p&gt;That’s not &lt;em&gt;role-based&lt;/em&gt; — that’s &lt;strong&gt;multiple-account chaos&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  💡 3. The Smarter Way — “User + Profiles”
&lt;/h2&gt;

&lt;p&gt;Here’s the scalable approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep &lt;strong&gt;shared user data&lt;/strong&gt; (like email, password, name) in a single &lt;code&gt;User&lt;/code&gt; table.&lt;/li&gt;
&lt;li&gt;Create &lt;strong&gt;separate tables for each role’s profile&lt;/strong&gt; (&lt;code&gt;AdminProfile&lt;/code&gt;, &lt;code&gt;VendorProfile&lt;/code&gt;, &lt;code&gt;CustomerProfile&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Let one user have &lt;strong&gt;multiple profiles&lt;/strong&gt; linked to them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;User&lt;/code&gt; is the person.&lt;br&gt;
The &lt;code&gt;Profiles&lt;/code&gt; are the hats they wear.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, Sarah can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in once ✅&lt;/li&gt;
&lt;li&gt;Buy products as a &lt;strong&gt;customer&lt;/strong&gt; 🛒&lt;/li&gt;
&lt;li&gt;Sell items as a &lt;strong&gt;vendor&lt;/strong&gt; 🏪&lt;/li&gt;
&lt;li&gt;Manage users as an &lt;strong&gt;admin&lt;/strong&gt; ⚙️&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All through one account.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧭 4. Visualizing It
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          +------------------+
          |      User        |
          |------------------|
          | id               |
          | name             |
          | email            |
          | passwordHash     |
          +--------+---------+
                   |
          +--------+---------+
          |                  |
  +----------------+  +----------------+
  | VendorProfile  |  | CustomerProfile|
  |----------------|  |----------------|
  | id             |  | id             |
  | userId (FK)    |  | userId (FK)    |
  | storeName      |  | walletBalance  |
  | businessType   |  | preferences    |
  +----------------+  +----------------+

          +----------------+
          |  AdminProfile  |
          |----------------|
          | id             |
          | userId (FK)    |
          | permissions[]  |
          | accessLevel    |
          +----------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚙️ 5. Schema Example (Prisma-style)
&lt;/h2&gt;

&lt;p&gt;Here’s what that looks like in a clean ORM setup:&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="nx"&gt;model&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;        &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;      &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;     &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;unique&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;  &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;createdAt&lt;/span&gt; &lt;span class="nx"&gt;DateTime&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

  &lt;span class="nx"&gt;adminProfile&lt;/span&gt;    &lt;span class="nx"&gt;AdminProfile&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
  &lt;span class="nx"&gt;vendorProfile&lt;/span&gt;   &lt;span class="nx"&gt;VendorProfile&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
  &lt;span class="nx"&gt;customerProfile&lt;/span&gt; &lt;span class="nx"&gt;CustomerProfile&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="nx"&gt;AdminProfile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;           &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;userId&lt;/span&gt;       &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;unique&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;         &lt;span class="nx"&gt;User&lt;/span&gt;   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;relation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;references&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="nx"&gt;permissions&lt;/span&gt;  &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="nx"&gt;accessLevel&lt;/span&gt;  &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="nx"&gt;VendorProfile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;           &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;userId&lt;/span&gt;       &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;unique&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;         &lt;span class="nx"&gt;User&lt;/span&gt;   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;relation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;references&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="nx"&gt;storeName&lt;/span&gt;    &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="nx"&gt;businessType&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="nx"&gt;CustomerProfile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;            &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;id&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nx"&gt;userId&lt;/span&gt;        &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;unique&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;          &lt;span class="nx"&gt;User&lt;/span&gt;   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;relation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;references&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="nx"&gt;walletBalance&lt;/span&gt; &lt;span class="nx"&gt;Float&lt;/span&gt;
  &lt;span class="nx"&gt;preferences&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s modular, readable, and future-proof.&lt;br&gt;
Adding a new role later? Just create a new profile table. No migrations. No mess.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 6. Real-World Example
&lt;/h2&gt;

&lt;p&gt;Meet &lt;strong&gt;Sarah&lt;/strong&gt;.&lt;br&gt;
She signs up on your platform.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;✅ Starts as a &lt;strong&gt;Customer&lt;/strong&gt; → creates a &lt;code&gt;CustomerProfile&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🏪 Opens her store → creates a &lt;code&gt;VendorProfile&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;⚙️ Joins your team → adds an &lt;code&gt;AdminProfile&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Still &lt;strong&gt;one login&lt;/strong&gt;, &lt;strong&gt;one token&lt;/strong&gt;, &lt;strong&gt;one user record&lt;/strong&gt;.&lt;br&gt;
She just switches context — your backend handles the rest.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 7. Why This Wins
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;Separation of concerns&lt;/strong&gt; — shared auth, separate business logic.&lt;br&gt;
✅ &lt;strong&gt;Extensible&lt;/strong&gt; — new roles = new tables, not new headaches.&lt;br&gt;
✅ &lt;strong&gt;Clean authorization&lt;/strong&gt; — role checks happen on profile level.&lt;br&gt;
✅ &lt;strong&gt;Reusable auth&lt;/strong&gt; — login once, access multiple contexts.&lt;br&gt;
✅ &lt;strong&gt;No null fields&lt;/strong&gt; — because every role owns its own schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 8. Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Good system design is like clean UI — invisible when done right.&lt;/p&gt;

&lt;p&gt;This &lt;strong&gt;User + Separate Profile Tables&lt;/strong&gt; approach gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flexibility&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;And peace of mind 😌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As your app grows, you’ll thank yourself for choosing this pattern.&lt;/p&gt;

&lt;p&gt;Because the next time someone says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We’re adding &lt;em&gt;moderators&lt;/em&gt; now…”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You’ll just smile and create a &lt;code&gt;ModeratorProfile&lt;/code&gt; table. 😎&lt;/p&gt;




&lt;h3&gt;
  
  
  💬 Coming Next
&lt;/h3&gt;

&lt;p&gt;In the next article in this series:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Role-Based Access Control (RBAC)&lt;/strong&gt; with User Profiles&lt;br&gt;
— How to attach permissions dynamically and secure routes in your backend elegantly.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>systemdesign</category>
      <category>softwareengineering</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>What Happens When You Type a URL in Your Browser? 🌐</title>
      <dc:creator>Abdul Basit Muhyideen</dc:creator>
      <pubDate>Mon, 20 Oct 2025 22:01:40 +0000</pubDate>
      <link>https://forem.com/kolardev/what-happens-when-you-type-a-url-in-your-browser-1hkn</link>
      <guid>https://forem.com/kolardev/what-happens-when-you-type-a-url-in-your-browser-1hkn</guid>
      <description>&lt;h1&gt;
  
  
  What Happens When You Type a URL in Your Browser? 🌐
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;The unseen journey of your request — explained for developers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You open your browser, type &lt;code&gt;www.google.com&lt;/code&gt;, and &lt;em&gt;boom&lt;/em&gt; — Google appears in seconds.&lt;/p&gt;

&lt;p&gt;But what &lt;em&gt;really&lt;/em&gt; happens in that tiny moment between hitting “Enter” and seeing the page load?&lt;/p&gt;

&lt;p&gt;Behind the scenes, dozens of technologies and protocols spring into action. It’s like a relay race between your browser, DNS servers, routers, and Google’s data centers — all in milliseconds.&lt;/p&gt;

&lt;p&gt;Let’s break it down step by step 👇&lt;/p&gt;




&lt;h2&gt;
  
  
  1. You Type the URL (and the Browser Gets to Work) 💻
&lt;/h2&gt;

&lt;p&gt;When you type &lt;code&gt;https://www.google.com&lt;/code&gt; and press Enter, your browser first breaks down that URL into pieces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Protocol&lt;/strong&gt; → &lt;code&gt;https://&lt;/code&gt; (how to communicate)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain name&lt;/strong&gt; → &lt;code&gt;www.google.com&lt;/code&gt; (where to go)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Path&lt;/strong&gt; → &lt;code&gt;/search&lt;/code&gt; (what resource to fetch, if any)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it’s your first visit, the browser doesn’t know where &lt;code&gt;www.google.com&lt;/code&gt; lives — so it has to &lt;em&gt;find&lt;/em&gt; the IP address. That’s where DNS comes in.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. DNS Lookup: Finding the Address 🗺️
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Domain Name System (DNS)&lt;/strong&gt; works like the Internet’s phonebook.&lt;/p&gt;

&lt;p&gt;When your browser asks, “Where is &lt;code&gt;google.com&lt;/code&gt;?” it goes through these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Browser Cache&lt;/strong&gt; – Has it been visited recently? If yes, it already knows the IP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OS Cache&lt;/strong&gt; – If not, your computer’s operating system checks next.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Router Cache&lt;/strong&gt; – Still not found? The router checks its local DNS cache.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ISP DNS Server&lt;/strong&gt; – Finally, your Internet provider queries a global DNS system to find the IP (like &lt;code&gt;142.250.190.4&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once found, the result is cached for faster access next time.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The Browser Opens a TCP Connection 🔗
&lt;/h2&gt;

&lt;p&gt;Now that your browser knows Google’s IP address, it can connect.&lt;/p&gt;

&lt;p&gt;It starts by creating a &lt;strong&gt;TCP connection&lt;/strong&gt; — the reliable communication link of the Internet.&lt;br&gt;
This is called the &lt;strong&gt;TCP handshake&lt;/strong&gt;, and it happens in 3 steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SYN&lt;/strong&gt; → Browser says, “Hey server, are you there?”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SYN-ACK&lt;/strong&gt; → Server replies, “Yes, I am. Ready?”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACK&lt;/strong&gt; → Browser confirms, “Let’s talk!”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This ensures both sides are ready to exchange data safely.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. HTTPS &amp;amp; TLS Handshake: Secure the Channel 🔒
&lt;/h2&gt;

&lt;p&gt;Because the URL uses &lt;strong&gt;HTTPS&lt;/strong&gt;, the connection must be &lt;strong&gt;secure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, after the TCP handshake, the browser and server perform a &lt;strong&gt;TLS handshake&lt;/strong&gt; (Transport Layer Security):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The server sends its &lt;strong&gt;SSL certificate&lt;/strong&gt; to prove its identity.&lt;/li&gt;
&lt;li&gt;The browser verifies the certificate (checking if it’s valid, trusted, and matches the domain).&lt;/li&gt;
&lt;li&gt;Both agree on &lt;strong&gt;encryption keys&lt;/strong&gt; to secure the session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once this is done, all data sent between your browser and the server is encrypted.&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Sending the HTTP Request 📩
&lt;/h2&gt;

&lt;p&gt;Finally, your browser sends an &lt;strong&gt;HTTP request&lt;/strong&gt; to the server.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;www.google.com&lt;/span&gt;
&lt;span class="na"&gt;User-Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Chrome/120.0&lt;/span&gt;
&lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells the server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The method (&lt;code&gt;GET&lt;/code&gt;) — “I want to read something.”&lt;/li&gt;
&lt;li&gt;The resource (&lt;code&gt;/&lt;/code&gt;) — the homepage.&lt;/li&gt;
&lt;li&gt;Browser details and supported content types.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. The Server Processes the Request ⚙️
&lt;/h2&gt;

&lt;p&gt;On Google’s end, powerful &lt;strong&gt;web servers&lt;/strong&gt; receive your request.&lt;/p&gt;

&lt;p&gt;Here’s what happens there:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The server routes your request to the correct backend service (for example, Google Search).&lt;/li&gt;
&lt;li&gt;Backend logic runs — retrieving data, rendering pages, calling APIs.&lt;/li&gt;
&lt;li&gt;The server generates a response, typically in HTML (or JSON for APIs).&lt;/li&gt;
&lt;/ol&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3050&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then comes the &lt;strong&gt;HTML document&lt;/strong&gt; — the skeleton of the web page.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Browser Renders the Page 🧠
&lt;/h2&gt;

&lt;p&gt;Once your browser receives the response, it gets busy again:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HTML Parsing&lt;/strong&gt; – Reads the HTML and builds the &lt;strong&gt;DOM&lt;/strong&gt; (Document Object Model).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS Parsing&lt;/strong&gt; – Loads styles and builds the &lt;strong&gt;CSSOM&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript Execution&lt;/strong&gt; – Runs scripts that may modify the DOM or fetch more data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layout &amp;amp; Painting&lt;/strong&gt; – Figures out where everything goes and paints pixels to your screen.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is when you &lt;em&gt;see&lt;/em&gt; the website appear — text, images, buttons, all beautifully arranged.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. More Requests Behind the Scenes 🔁
&lt;/h2&gt;

&lt;p&gt;Even after the main HTML loads, the browser continues fetching:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Images (&lt;code&gt;.jpg&lt;/code&gt;, &lt;code&gt;.png&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;CSS stylesheets&lt;/li&gt;
&lt;li&gt;JavaScript files&lt;/li&gt;
&lt;li&gt;Fonts&lt;/li&gt;
&lt;li&gt;APIs for dynamic data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these makes its own HTTP request to the server (or CDNs). That’s why browsers load resources in parallel for speed.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Caching, Cookies, and Performance 🍪
&lt;/h2&gt;

&lt;p&gt;Before finishing, the browser checks caching rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cache-Control headers&lt;/strong&gt; decide if the resource can be reused.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cookies&lt;/strong&gt; might be stored or sent back for authentication or personalization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compression (like GZIP or Brotli)&lt;/strong&gt; helps reduce file sizes for faster loading.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these optimizations ensure that the &lt;em&gt;next&lt;/em&gt; visit feels instant.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. You See the Page ✨
&lt;/h2&gt;

&lt;p&gt;And there you have it — a full journey completed in &lt;strong&gt;under a second&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;From typing a URL to seeing a page, here’s what just happened:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You entered a URL&lt;/li&gt;
&lt;li&gt;DNS resolved the domain&lt;/li&gt;
&lt;li&gt;TCP &amp;amp; TLS handshakes secured the channel&lt;/li&gt;
&lt;li&gt;HTTP request sent&lt;/li&gt;
&lt;li&gt;Server processed and responded&lt;/li&gt;
&lt;li&gt;Browser rendered and displayed the content&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All these layers work together — perfectly synchronized — to give you the illusion of instant access.&lt;/p&gt;




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

&lt;p&gt;Every time you type a URL, you trigger an orchestra of systems, protocols, and servers that collaborate to deliver what you see.&lt;/p&gt;

&lt;p&gt;For backend engineers, understanding this flow is gold:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You’ll know where latency creeps in.&lt;/li&gt;
&lt;li&gt;You’ll grasp how APIs communicate.&lt;/li&gt;
&lt;li&gt;You’ll understand why DNS, SSL, and caching matter so much.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next up in the series: &lt;strong&gt;“Understanding HTTP and HTTPS — The Internet’s Communication Language.”&lt;/strong&gt; 🚀&lt;/p&gt;

</description>
      <category>programming</category>
      <category>howtheinternetworks</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>How the Internet Works (Simplified for Developers)</title>
      <dc:creator>Abdul Basit Muhyideen</dc:creator>
      <pubDate>Sun, 05 Oct 2025 21:03:14 +0000</pubDate>
      <link>https://forem.com/kolardev/how-the-internet-works-simplified-for-developers-3078</link>
      <guid>https://forem.com/kolardev/how-the-internet-works-simplified-for-developers-3078</guid>
      <description>&lt;p&gt;Ever wondered what really happens when you hit “Send” on WhatsApp, or type google.com into your browser?&lt;br&gt;
 Spoiler: your data doesn’t just teleport. The Internet is more like the world’s busiest postal system—except instead of envelopes and delivery trucks, we have packets, routers, and cables running under the ocean.&lt;/p&gt;

&lt;p&gt;As backend engineers, this isn’t just trivia. The Internet is the foundation for APIs, databases, and cloud apps. Let’s break it down — no jargon overload, just the essentials.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Internet as a Giant Network 🌍&lt;/strong&gt;
Think of the Internet as a massive web of connected computers — servers, laptops, phones, IoT devices.
These devices talk to each other through wires, fiber optics, satellites, and wireless signals.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;👉 &lt;strong&gt;Analogy&lt;/strong&gt;: Every device is like a house, and the data you send is a letter. The Internet is the postal system making sure it gets delivered.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Data Travels as Packets&lt;/strong&gt; 📦
When you send a message or load a webpage, your data doesn’t travel in one big piece. Instead, it’s broken into small chunks called packets.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each packet carries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A piece of your data (like a puzzle piece)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The sender’s address (your IP)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The receiver’s address (destination IP)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Packets often take different routes through the network and get reassembled at the destination.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;IP Addresses&lt;/strong&gt; = Digital Street Addresses 🏠
Every device online has an IP address (like 192.168.0.1 or 2607:f8b0::).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;IPv4&lt;/strong&gt;: Old system, running out of addresses&lt;br&gt;
&lt;strong&gt;IPv6&lt;/strong&gt;: Modern system, almost unlimited addresses&lt;br&gt;
Without IP addresses, your data wouldn’t know where to go.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;DNS&lt;/strong&gt;: The Internet’s Phonebook ☎️
Humans don’t like memorizing IPs (172.217.5.110 isn’t fun). Instead, we use domain names like google.com.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Domain Name System (DNS) is like a phonebook — it translates names into addresses.&lt;br&gt;
So when you type google.com, DNS quietly finds its IP for you.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Internet’s Infrastructure&lt;/strong&gt; ⚙️
Behind the scenes, the Internet is powered by:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ISPs: Give you access (your local “post office”)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Routers &amp;amp; Switches: Direct traffic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Servers &amp;amp; Data Centers: Store and serve content&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Undersea Cables &amp;amp; Satellites: Connect continents&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fun fact: Most of the Internet’s traffic actually travels through underwater cables, not satellites.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Protocols&lt;/strong&gt;: The Rules of Communication 📡
Computers don’t just “wing it.” They follow strict rules called protocols:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;TCP/IP&lt;/strong&gt;: Splits data into packets, ensures delivery&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTTP/HTTPS&lt;/strong&gt;: Browser ↔ server communication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SMTP&lt;/strong&gt;: Emails in action&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of protocols as the grammar of the Internet — without them, computers would just be babbling nonsense.&lt;/p&gt;

&lt;p&gt;Wrapping Up 🎁&lt;br&gt;
At its core, the Internet is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A network of devices (the houses)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sending packets of data (letters)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Across infrastructure (roads, post offices)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using protocols (the rules of delivery)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For backend engineers, this foundation explains why APIs work, why latency exists, and how scaling apps ties back to the Internet’s plumbing.&lt;/p&gt;

&lt;p&gt;Next up in this series: “What Happens When You Type a URL in Your Browser?” 🔥&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>networking</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
