<?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: Rushikesh Surve</title>
    <description>The latest articles on Forem by Rushikesh Surve (@rushier).</description>
    <link>https://forem.com/rushier</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%2F3098554%2F57d73e9b-0b08-4433-aec1-5b031a582f9e.png</url>
      <title>Forem: Rushikesh Surve</title>
      <link>https://forem.com/rushier</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rushier"/>
    <language>en</language>
    <item>
      <title>Microservices Authentication &amp; Authorization: A Beginner's Guide</title>
      <dc:creator>Rushikesh Surve</dc:creator>
      <pubDate>Wed, 26 Nov 2025 18:26:32 +0000</pubDate>
      <link>https://forem.com/rushier/microservices-authentication-authorization-a-beginners-guide-1hde</link>
      <guid>https://forem.com/rushier/microservices-authentication-authorization-a-beginners-guide-1hde</guid>
      <description>&lt;p&gt;Hello there! If you've ever felt overwhelmed by the idea of securing a microservices architecture, you are not alone. It's a common stumbling block. In a monolithic app, you just check the session in one place. But when you have 5, 10, or 50 services, how do you make sure only the right people get in?&lt;/p&gt;

&lt;p&gt;Today, we're going to build a robust, production-ready authentication flow using Node.js. We'll use a pattern that is both scalable and easy to understand: &lt;strong&gt;Gateway Authentication and Service-Level Authorization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you'll have a working system with 3 services:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;API Gateway&lt;/strong&gt;: The entry point (The Bouncer).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Auth Service&lt;/strong&gt;: Handles Login (The ID Issuer).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Custom Service&lt;/strong&gt;: A demo service with Public, User, and Admin routes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's dive in!&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;Before we write code, let's visualize what we are building.&lt;/p&gt;

&lt;p&gt;We want a central entry point (API Gateway) that handles the "Who are you?" question (Authentication). Once confirmed, it passes the request to the specific service, which handles the "Are you allowed here?" question (Authorization).&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%2Fdk57weh54e2gmdgf3fb1.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%2Fdk57weh54e2gmdgf3fb1.png" alt="Microservice Auth Architecture - Gateway Offloading Pattern" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;Let's keep it simple. We'll simulate three services in one folder for this demo.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a folder&lt;/strong&gt; and initialize:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;microservices-auth-demo
&lt;span class="nb"&gt;cd &lt;/span&gt;microservices-auth-demo
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install Dependencies&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;express jsonwebtoken http-proxy-middleware dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Folder Structure&lt;/strong&gt;:&lt;br&gt;
Create three folders inside:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;auth-service&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gateway&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;custom-service&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 1: The Auth Service
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The Identity Provider&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This service is responsible for validating credentials and issuing tokens.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;auth-service/index.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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;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;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;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;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;super-secret-key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Mock User Database&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alice&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&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="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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bob&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&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;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;username&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="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;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;users&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;u&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;password&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;user&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;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="mi"&gt;401&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="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid credentials&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;// Generate Token with Role&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;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="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;user&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;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; 
        &lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1h&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;res&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;token&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3001&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="s1"&gt;Auth Service running on port 3001&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: The API Gateway
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The Bouncer&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Gateway intercepts requests. It needs to know which routes are &lt;strong&gt;Public&lt;/strong&gt; and which are &lt;strong&gt;Protected&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We want:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;/auth&lt;/code&gt; -&amp;gt; &lt;strong&gt;Public&lt;/strong&gt; (Login)&lt;/li&gt;
&lt;li&gt; &lt;code&gt;/custom/public&lt;/code&gt; -&amp;gt; &lt;strong&gt;Public&lt;/strong&gt; (No token needed)&lt;/li&gt;
&lt;li&gt; &lt;code&gt;/custom&lt;/code&gt; (everything else) -&amp;gt; &lt;strong&gt;Protected&lt;/strong&gt; (Token required)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create &lt;code&gt;gateway/index.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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createProxyMiddleware&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http-proxy-middleware&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;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;super-secret-key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// --- Authentication Middleware ---&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;verifyToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="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;authHeader&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authorization&lt;/span&gt;&lt;span class="dl"&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;authHeader&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;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="mi"&gt;401&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="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No token provided&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;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;authHeader&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="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&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="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;decoded&lt;/span&gt; &lt;span class="o"&gt;=&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;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Pass user info to downstream via Headers&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-user-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;decoded&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;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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-user-role&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&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;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;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="mi"&gt;401&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="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid token&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;// --- Routes ---&lt;/span&gt;

&lt;span class="c1"&gt;// 1. Auth Service (Public)&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;/auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;createProxyMiddleware&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
    &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3001&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;changeOrigin&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;pathRewrite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^/auth&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="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Custom Service - Public Endpoint&lt;/span&gt;
&lt;span class="c1"&gt;// Note: We place this BEFORE the protected route so it matches first!&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;/custom/public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;createProxyMiddleware&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
    &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3002&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;changeOrigin&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="c1"&gt;// We don't rewrite path here because we want the service to receive '/public'&lt;/span&gt;
    &lt;span class="c1"&gt;// But wait, if we forward '/custom/public' to localhost:3002/custom/public, &lt;/span&gt;
    &lt;span class="c1"&gt;// the service needs to listen on /custom/public OR we rewrite.&lt;/span&gt;
    &lt;span class="c1"&gt;// Let's rewrite so the service just sees '/public'&lt;/span&gt;
    &lt;span class="na"&gt;pathRewrite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^/custom&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="p"&gt;},&lt;/span&gt; 
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="c1"&gt;// 3. Custom Service - Protected Endpoints&lt;/span&gt;
&lt;span class="c1"&gt;// Everything else under /custom requires a token&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;/custom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;verifyToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;createProxyMiddleware&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
    &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3002&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;changeOrigin&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;pathRewrite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^/custom&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="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&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="s1"&gt;API Gateway running on port 3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: The Custom Service
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The VIP Area&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This service has 3 types of routes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Public&lt;/strong&gt;: Accessible by anyone (Gateway let it through).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Protected (User)&lt;/strong&gt;: Accessible by any logged-in user.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Protected (Admin)&lt;/strong&gt;: Accessible only by admins.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create &lt;code&gt;custom-service/index.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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// --- Authorization Middleware ---&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;requireRole&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allowedRole&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;userRole&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-user-role&lt;/span&gt;&lt;span class="dl"&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;userRole&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;allowedRole&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;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="mi"&gt;403&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="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Forbidden: Admins only&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="nf"&gt;next&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;// 1. Public Route&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is a public endpoint. Everyone is welcome!&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;// 2. Protected Route (Any Authenticated User)&lt;/span&gt;
&lt;span class="c1"&gt;// If the request reached here via the protected Gateway route, &lt;/span&gt;
&lt;span class="c1"&gt;// it MUST have headers.&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-user-id&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;userRole&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-user-role&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is a protected endpoint.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;user&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;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userRole&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;// 3. Protected Route (Admin Only)&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;requireRole&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="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome to the Admin Dashboard!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3002&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="s1"&gt;Custom Service running on port 3002&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Testing It Out
&lt;/h2&gt;

&lt;p&gt;Open 3 terminal windows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;node auth-service/index.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;code&gt;node custom-service/index.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;code&gt;node gateway/index.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Scenario A: Public Route (No Token)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:3000/custom/public
&lt;span class="c"&gt;# Output: {"message":"This is a public endpoint. Everyone is welcome!"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Result: Success! Gateway let it through without checking auth.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario B: Protected Route (No Token)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:3000/custom/profile
&lt;span class="c"&gt;# Output: {"message":"No token provided"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Result: Blocked by Gateway.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario C: Login as 'bob' (User)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3000/auth/login &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"username":"bob", "password":"password123"}'&lt;/span&gt;
&lt;span class="c"&gt;# Copy the token...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Scenario D: Access Profile (User Role)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:3000/custom/profile &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;BOB_TOKEN&amp;gt;"&lt;/span&gt;
&lt;span class="c"&gt;# Output: {"message":"This is a protected endpoint.", "user":{...}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Result: Success!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario E: Access Admin (User Role)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:3000/custom/admin &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;BOB_TOKEN&amp;gt;"&lt;/span&gt;
&lt;span class="c"&gt;# Output: {"message":"Forbidden: Admins only"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Result: Blocked by Service (AuthZ).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario F: Access Admin (Admin Role)&lt;/strong&gt;&lt;br&gt;
Login as &lt;code&gt;alice&lt;/code&gt; and try again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:3000/custom/admin &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;ALICE_TOKEN&amp;gt;"&lt;/span&gt;
&lt;span class="c"&gt;# Output: {"message":"Welcome to the Admin Dashboard!"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Result: Success!&lt;/em&gt;&lt;/p&gt;




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

&lt;p&gt;You now have a flexible system. The &lt;strong&gt;Gateway&lt;/strong&gt; handles the heavy lifting of checking tokens for protected routes, while allowing public routes to bypass it. The &lt;strong&gt;Services&lt;/strong&gt; enforce fine-grained permissions.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>authentication</category>
      <category>authorization</category>
      <category>gateway</category>
    </item>
    <item>
      <title>🐳 Docker Deserves a Place Beside Git — Here’s Why</title>
      <dc:creator>Rushikesh Surve</dc:creator>
      <pubDate>Thu, 20 Nov 2025 11:50:17 +0000</pubDate>
      <link>https://forem.com/rushier/docker-deserves-a-place-beside-git-heres-why-3444</link>
      <guid>https://forem.com/rushier/docker-deserves-a-place-beside-git-heres-why-3444</guid>
      <description>&lt;p&gt;Most developers learn &lt;strong&gt;Git&lt;/strong&gt; early in their journey — and they absolutely should. Version control is the safety net that allows us to experiment, break things, and collaborate without losing our minds.&lt;/p&gt;

&lt;p&gt;But there’s another tool that deserves &lt;strong&gt;equal priority&lt;/strong&gt; in every developer’s toolkit, right from day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  👉 Docker.
&lt;/h2&gt;

&lt;p&gt;Not "later." Not "once you’re a senior engineer." It belongs right beside Git. Here is why.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎒 The Pain of Revisiting Old Projects
&lt;/h2&gt;

&lt;p&gt;When I started building projects in college, every semester introduced a completely new tech stack.&lt;/p&gt;

&lt;p&gt;One month I was juggling &lt;strong&gt;Node.js and MongoDB&lt;/strong&gt;; the next, I was wrestling with &lt;strong&gt;PHP, XAMPP, and MySQL&lt;/strong&gt;. By the end of the year, I was configuring &lt;strong&gt;Spring Boot with PostgreSQL&lt;/strong&gt;, or dabbling in Python for data science assignments.&lt;/p&gt;

&lt;p&gt;To save system resources (and my sanity), I would routinely uninstall tools I wasn't actively using. It felt harmless at the time—until interview season arrived.&lt;/p&gt;

&lt;p&gt;I wanted to polish my old projects to showcase them in my portfolio, fix a few bugs, and demonstrate my growth to recruiters. But when I tried to open them to get them ready for a demo, I hit a wall.&lt;/p&gt;

&lt;h3&gt;
  
  
  The "Code Rot" Illusion
&lt;/h3&gt;

&lt;p&gt;Suddenly, a project that worked perfectly six months ago became a nightmare to revive.&lt;/p&gt;

&lt;p&gt;It wasn't that the code had changed—the &lt;strong&gt;environment&lt;/strong&gt; had. I found myself wasting hours reinstalling outdated versions of languages, fixing broken configuration files, and trying to remember exactly how I had set up the local variables. Services refused to start, and ports were conflicting.&lt;/p&gt;

&lt;p&gt;I realized the hard truth: &lt;strong&gt;The code was fine. The context was gone.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 The Failed Workarounds
&lt;/h2&gt;

&lt;p&gt;Before I embraced containerization, I tried several "patches" to solve this, but none were actual solutions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Switching everything to SQLite:&lt;/strong&gt; I tried to avoid database servers entirely by using file-based DBs. It reduced dependencies, but it caused massive headaches when moving to production or dealing with features that SQLite didn't support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VirtualBox VMs:&lt;/strong&gt; This worked, technically. But keeping a full Operating System image for every small project was heavy, slow, and consumed terabytes of storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detailed "Setup.md" files:&lt;/strong&gt; I tried writing manual instructions for my future self. But let's be honest—documentation goes out of date the moment you write it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything felt like a band-aid.&lt;/p&gt;




&lt;h2&gt;
  
  
  🐳 Discovering Docker Changed Everything
&lt;/h2&gt;

&lt;p&gt;Docker solved this problem so elegantly that I still regret not learning it earlier.&lt;/p&gt;

&lt;p&gt;Instead of installing Node, Python, or Postgres directly onto my laptop, I started &lt;strong&gt;containerizing&lt;/strong&gt; them. By defining the frontend, backend, database, and all supporting services in code, my projects became &lt;strong&gt;portable&lt;/strong&gt; and &lt;strong&gt;reproducible&lt;/strong&gt;, completely independent of my host system.&lt;/p&gt;

&lt;p&gt;Now, when I want to revive a project from 2021, the process is incredibly simple:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;And just like that, the project comes back to life exactly as it was.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No&lt;/strong&gt; reinstalling languages. &lt;strong&gt;No&lt;/strong&gt; dependency mismatches. &lt;strong&gt;No&lt;/strong&gt; breaking changes because my OS updated.&lt;/p&gt;

&lt;p&gt;When I'm done? I stop the containers, and my system stays clean.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 Git vs. Docker — A Perfect Combination
&lt;/h2&gt;

&lt;p&gt;If you are wondering how they fit together, think of it this way:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;The Question it Answers&lt;/th&gt;
&lt;th&gt;The Benefit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Git&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"What changed in the code?"&lt;/td&gt;
&lt;td&gt;Protects your history.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Where and how does it run?"&lt;/td&gt;
&lt;td&gt;Protects your environment.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Together, they make your projects &lt;strong&gt;future-proof&lt;/strong&gt;. Git allows you to share the logic, while Docker ensures that the logic runs exactly the same way on your machine, your friend's laptop, and the production server.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;If you are a new developer, or just someone tired of "it works on my machine" syndrome:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Learn Git for collaboration. Learn Docker for sustainability.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One protects your code. The other protects your environment. Use both, and your projects will outlive your laptop, your OS, and even your memory of how they worked.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this resonates with your experiences (or your frustrations with &lt;code&gt;npm install&lt;/code&gt; failing on an old project!), feel free to share your story in the comments.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy coding! 🚀&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>docker</category>
      <category>devops</category>
      <category>git</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🧠 Download Smarter: Using Colab + Google Drive to Bypass Slow Direct Downloads</title>
      <dc:creator>Rushikesh Surve</dc:creator>
      <pubDate>Sun, 22 Jun 2025 17:04:37 +0000</pubDate>
      <link>https://forem.com/rushier/download-smarter-using-colab-google-drive-to-bypass-slow-direct-downloads-2e7a</link>
      <guid>https://forem.com/rushier/download-smarter-using-colab-google-drive-to-bypass-slow-direct-downloads-2e7a</guid>
      <description>&lt;h3&gt;
  
  
  🧭 Introduction
&lt;/h3&gt;

&lt;p&gt;Sometimes, downloading large files directly to your local system can be painfully slow, especially when the source server is far away, overloaded, or unstable.&lt;/p&gt;

&lt;p&gt;In such cases, I found a neat trick using &lt;strong&gt;Google Colab&lt;/strong&gt; and &lt;strong&gt;Python&lt;/strong&gt; to speed things up, by &lt;strong&gt;downloading the file into my Google Drive first&lt;/strong&gt;, and then fetching it from there when convenient.&lt;/p&gt;

&lt;p&gt;This blog shares:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A working Python script (using &lt;code&gt;gdown&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Why this method &lt;em&gt;might&lt;/em&gt; be faster in some cases&lt;/li&gt;
&lt;li&gt;When it’s worth using (and when it might not help)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ⚙️ The Idea: Use Google’s Speed to Your Advantage
&lt;/h3&gt;

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

&lt;ol&gt;
&lt;li&gt;Run a small script in &lt;strong&gt;&lt;a href="https://colab.research.google.com/#create=true" rel="noopener noreferrer"&gt;Google Colab&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Let &lt;strong&gt;Google’s servers&lt;/strong&gt; download the file into your &lt;strong&gt;Google Drive&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Later, download it to your device, often faster and more reliably than from the original source.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This has worked well for downloading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📽️ Movies&lt;/li&gt;
&lt;li&gt;📚 PDFs and eBooks&lt;/li&gt;
&lt;li&gt;🧩 Software packages and installers&lt;/li&gt;
&lt;li&gt;🎮 Game files&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📜 The Python Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Step 1: Install required libraries
&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;gdown&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.colab&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;drive&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;gdown&lt;/span&gt;

&lt;span class="c1"&gt;# Step 2: Mount Google Drive
&lt;/span&gt;&lt;span class="n"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/content/drive&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Step 3: Function to download file
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;download_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;save_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="c1"&gt;# Extract the original file name from the URL
&lt;/span&gt;    &lt;span class="n"&gt;file_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Download the file from the given URL
&lt;/span&gt;    &lt;span class="n"&gt;gdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;download&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;save_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;quiet&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Example usage
&lt;/span&gt;&lt;span class="n"&gt;file_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://file-examples.com/storage/feac45e876684fd51a206f4/2017/04/file_example_MP4_1920_18MG.mp4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;save_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/content/drive/MyDrive/Colab Notebooks/Downloads/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;  &lt;span class="c1"&gt;# Specify your folder
&lt;/span&gt;
&lt;span class="c1"&gt;# Download the file
&lt;/span&gt;&lt;span class="nf"&gt;download_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;save_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Download completed!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ Make sure the URL ends with file name and extension (a direct download link)&lt;/p&gt;




&lt;h4&gt;
  
  
  🖥️ Executing the Script in Colab
&lt;/h4&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%2Fzgevlr9anqzpg4dgr7ad.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%2Fzgevlr9anqzpg4dgr7ad.png" alt="Executing script" width="800" height="389"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Running the Python script inside Google Colab. Once executed, the file starts downloading to your Google Drive.&lt;/em&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  📂 File Saved in Google Drive
&lt;/h4&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%2Fbblet4vpkpskv6xi0u6c.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%2Fbblet4vpkpskv6xi0u6c.png" alt="File in Google Drive" width="800" height="561"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The downloaded file appears neatly in your specified Google Drive folder, ready to download or organize.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  💡 Why Might This Be Faster?
&lt;/h3&gt;

&lt;p&gt;To be honest, this part is partly based on my &lt;strong&gt;observations&lt;/strong&gt; and &lt;strong&gt;assumptions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚡ Google Colab runs on &lt;strong&gt;Google’s own infrastructure&lt;/strong&gt;, high-speed servers with great bandwidth.&lt;/li&gt;
&lt;li&gt;🌍 Google Drive is likely &lt;strong&gt;replicated across multiple regions&lt;/strong&gt;, so downloading from it might be faster depending on where you are.&lt;/li&gt;
&lt;li&gt;⏳ Some direct file downloads are &lt;strong&gt;rate-limited&lt;/strong&gt; or unreliable, but Google Drive rarely is.&lt;/li&gt;
&lt;li&gt;🧠 Plus, once the file is in your Drive, &lt;strong&gt;you control it&lt;/strong&gt;, you can rename, organize, or download it anytime, even if the original source goes offline.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🤔 But Is This Always Better?
&lt;/h3&gt;

&lt;p&gt;Not necessarily. Here are a few considerations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Should You Use This Method?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;File is huge and downloads slowly&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Source server is flaky or unreliable&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File needs to be saved long-term&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You're on a fast network, direct is stable&lt;/td&gt;
&lt;td&gt;❌ Probably not&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File is behind a login / not public&lt;/td&gt;
&lt;td&gt;⚠️ May not work without auth headers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So yes, this trick won’t &lt;em&gt;magically&lt;/em&gt; speed up every download, but when it works, it can feel like magic ✨&lt;/p&gt;




&lt;h3&gt;
  
  
  🗣️ Final Thoughts
&lt;/h3&gt;

&lt;p&gt;This might not be a universal solution, but for me, it’s been a smart workaround, especially for those annoying moments when a 1 GB file says “5 hours remaining.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it out next time your download speed is crawling, and let me know if it helps!&lt;/strong&gt;&lt;br&gt;
Happy downloading 🚀&lt;/p&gt;




</description>
      <category>python</category>
      <category>downloads</category>
      <category>tricks</category>
      <category>googlecolab</category>
    </item>
    <item>
      <title>Learn to Use Microsoft OneNote for Note-Taking Without Getting Overwhelmed — A Steady Start</title>
      <dc:creator>Rushikesh Surve</dc:creator>
      <pubDate>Wed, 11 Jun 2025 12:13:58 +0000</pubDate>
      <link>https://forem.com/rushier/learn-to-use-microsoft-onenote-for-note-taking-without-getting-overwhelmed-a-steady-start-5dcb</link>
      <guid>https://forem.com/rushier/learn-to-use-microsoft-onenote-for-note-taking-without-getting-overwhelmed-a-steady-start-5dcb</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I’ve tried Microsoft OneNote multiple times in the past — and each time, I gave up. It felt overwhelming, messy, and just… too much.&lt;/p&gt;

&lt;p&gt;But recently, I tried something different: instead of expecting to master it in one go, I gave myself permission to &lt;strong&gt;start slow&lt;/strong&gt; — step by step. That one mindset shift changed everything.&lt;/p&gt;

&lt;p&gt;In this post, I’ll show you a simple system I now use to take notes in OneNote without ever feeling lost. If you're a student, developer, or just someone trying to organize your learning — this steady start is for you.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧱 &lt;strong&gt;Understanding the OneNote Structure&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To make the most of OneNote, you need to understand its basic hierarchy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📓 &lt;strong&gt;Notebook&lt;/strong&gt; – Think of this as your physical notebook or subject.&lt;/li&gt;
&lt;li&gt;🗂️ &lt;strong&gt;Section&lt;/strong&gt; – A divider in your notebook, like "Chapters" or "Topics".&lt;/li&gt;
&lt;li&gt;📄 &lt;strong&gt;Page&lt;/strong&gt; – A single page where you write stuff, like an actual note.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This hierarchy becomes super powerful &lt;strong&gt;once you stop trying to structure everything from Day 1&lt;/strong&gt; — and instead, let it grow naturally.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠️ &lt;strong&gt;The Simple “Grow-As-You-Go” System I Follow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here's the approach that worked for me:&lt;/p&gt;




&lt;h4&gt;
  
  
  ✅ Step 1: Create a General Notebook
&lt;/h4&gt;

&lt;p&gt;I created a notebook called &lt;strong&gt;"Learnings"&lt;/strong&gt; — a kind of catch-all space for everything I learn.&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%2F8lsgkiovnoradffb8osj.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%2F8lsgkiovnoradffb8osj.png" alt="Creating a general-purpose notebook to begin your journey." width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No stress, no structure. Just a starting point.&lt;/p&gt;




&lt;h4&gt;
  
  
  ✅ Step 2: Start with a Single Section
&lt;/h4&gt;

&lt;p&gt;You don’t need to create multiple sections upfront. Just create one section — name it anything like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Quick Notes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interesting Reads&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Knowledge Dump&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&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%2F8m877r732oo94n2q5i15.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%2F8m877r732oo94n2q5i15.png" alt="Add a simple section inside your notebook. Keep it general in the beginning." width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  ✅ Step 3: Add Pages Smartly
&lt;/h4&gt;

&lt;p&gt;Whenever I come across something worth saving — a concept, tip, or technique — I create a new page using this naming format:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;"Subject: Title of the Note"&lt;/code&gt;&lt;br&gt;
Example: &lt;code&gt;"Java: Encapsulation"&lt;/code&gt; or &lt;code&gt;"OS: Paging"&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&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%2Fjd6xeih76oz8jz05ml7f.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%2Fjd6xeih76oz8jz05ml7f.png" alt="Use a clear naming format like ‘Subject: Topic’ for each page." width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This format helps later when I want to filter or move similar notes together.&lt;/p&gt;




&lt;h4&gt;
  
  
  ✅ Step 4: Organize When It Starts to Get Crowded
&lt;/h4&gt;

&lt;p&gt;Once I notice a bunch of pages around the same subject, I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;strong&gt;new Section&lt;/strong&gt; for that subject in the same notebook.&lt;/li&gt;
&lt;li&gt;Move the related pages into that Section.&lt;/li&gt;
&lt;/ul&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%2F04d6viy57gb677eueme4.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%2F04d6viy57gb677eueme4.png" alt="Move related pages into a newly created section for better clarity." width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This step is the key: &lt;strong&gt;Don’t start with too much structure — let the content demand it.&lt;/strong&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  ✅ Step 5: Split Into New Notebooks (When Needed)
&lt;/h4&gt;

&lt;p&gt;If a single subject becomes too large (like 10+ pages and 3–4 sections), that’s when I finally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;strong&gt;dedicated Notebook&lt;/strong&gt; for that subject. (e.g., &lt;code&gt;Java&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Create relevant &lt;strong&gt;Sections&lt;/strong&gt; (e.g., &lt;code&gt;Data Types&lt;/code&gt;, &lt;code&gt;OOP Concepts&lt;/code&gt;, &lt;code&gt;Interesting Programs&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Move your old notes into the new structure.&lt;/li&gt;
&lt;/ul&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%2Fknfa9ipq1tb4bse94e7y.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%2Fknfa9ipq1tb4bse94e7y.png" alt="Create subject-specific notebooks once the content gets large." width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I’ve got a dedicated space for in-depth learning — organized, scalable, and never overwhelming.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔄 Repeat the Process
&lt;/h3&gt;

&lt;p&gt;This system works beautifully across multiple subjects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Web Development&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Machine Learning&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Interview Prep&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Dev Tools &amp;amp; Tricks&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just let the content pile up first, and reorganize only &lt;strong&gt;when it’s worth it&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎯 Final Thoughts
&lt;/h3&gt;

&lt;p&gt;OneNote is incredibly powerful — once you stop trying to master it all at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with one notebook, one section, one note.&lt;/strong&gt;&lt;br&gt;
Let your learning drive the structure — not the other way around.&lt;/p&gt;

&lt;p&gt;If you’ve ever felt overwhelmed with note-taking, try this “steady start” method. It worked for me, and I hope it works for you too.&lt;/p&gt;




</description>
      <category>onenote</category>
      <category>productivity</category>
      <category>notetaking</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>🚀 TL;DR: Create System Architecture Diagrams Instantly Using Claude AI + draw.io</title>
      <dc:creator>Rushikesh Surve</dc:creator>
      <pubDate>Mon, 05 May 2025 04:37:27 +0000</pubDate>
      <link>https://forem.com/rushier/tldr-create-system-architecture-diagrams-instantly-using-claude-ai-drawio-io3</link>
      <guid>https://forem.com/rushier/tldr-create-system-architecture-diagrams-instantly-using-claude-ai-drawio-io3</guid>
      <description>&lt;p&gt;Designing architecture diagrams for your project? Skip the drag-and-drop hassle. Use Claude AI to generate draw.io diagrams instantly with just a prompt.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Why Use This?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🧠 Claude AI generates &lt;strong&gt;draw.io-compatible XML&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;⚡ Instantly visualize system architectures&lt;/li&gt;
&lt;li&gt;💻 No design skills required – just describe your system&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠 How It Works (3 Simple Steps)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Prompt Claude AI&lt;/strong&gt; with something like:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generate a draw.io-compatible XML diagram for this project/code/pseudocode etc. 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;[And provide it the base content]&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Copy Claude's Output into a 'test.drawio' file&lt;/strong&gt; (XML code)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Import into draw.io&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open &lt;a href="https://app.diagrams.net" rel="noopener noreferrer"&gt;draw.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;File → Import from → Device&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;test.drawio&lt;/code&gt; file&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🧩 Sample Prompt
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generate an architecture diagram for a full-stack MERN app with auth, database, backend, and frontend layers. Output XML for draw.io.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude will reply with XML like this (trimmed for preview):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;mxfile&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;diagram&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"MERN App Architecture"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- XML content here --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/diagram&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/mxfile&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔥 Why It's Useful
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Saves &lt;strong&gt;30+ minutes&lt;/strong&gt; of manual diagramming
&lt;/li&gt;
&lt;li&gt;Great for docs, pitches, and planning
&lt;/li&gt;
&lt;li&gt;Works with &lt;strong&gt;any app idea&lt;/strong&gt; you describe&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally inspired by my full blog: &lt;a href="https://dev.to/rushier/how-to-use-claude-ai-drawio-to-create-architecture-diagrams-for-projects-17i1"&gt;How to Use Claude AI + draw.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>diagram</category>
      <category>tldr</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to use Claude AI + draw.io to Create Architecture Diagrams for Projects</title>
      <dc:creator>Rushikesh Surve</dc:creator>
      <pubDate>Tue, 29 Apr 2025 03:46:34 +0000</pubDate>
      <link>https://forem.com/rushier/how-to-use-claude-ai-drawio-to-create-architecture-diagrams-for-projects-17i1</link>
      <guid>https://forem.com/rushier/how-to-use-claude-ai-drawio-to-create-architecture-diagrams-for-projects-17i1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In technical engineering projects, especially those involving software system designs, &lt;strong&gt;professional diagrams&lt;/strong&gt; play a critical role in &lt;strong&gt;simplifying complexity&lt;/strong&gt; and &lt;strong&gt;enhancing communication&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
In this blog, I'll walk you through how I combine &lt;strong&gt;Claude AI&lt;/strong&gt; with &lt;strong&gt;draw.io&lt;/strong&gt; to create clean, structured, and visually appealing diagrams for complex codebases.&lt;/p&gt;

&lt;p&gt;We’ll demonstrate using a slightly complex system:&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Online Course Registration System (with Admin + Payment integration).&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Visual Diagrams Are Essential for Engineers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📈 Improve project documentation quality&lt;/li&gt;
&lt;li&gt;🧠 Clarify system architecture and workflows&lt;/li&gt;
&lt;li&gt;🖼️ Impress during project evaluations, internships, and freelancing&lt;/li&gt;
&lt;li&gt;🛠️ Save time during collaboration and debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether it’s &lt;strong&gt;API design&lt;/strong&gt;, &lt;strong&gt;microservices&lt;/strong&gt;, &lt;strong&gt;database flow&lt;/strong&gt;, or &lt;strong&gt;user journey&lt;/strong&gt;, good diagrams are crucial.&lt;/p&gt;




&lt;h3&gt;
  
  
  📋 Problem Statement
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Design a backend flow for an &lt;strong&gt;Online Course Registration System&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Key Components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Student&lt;/strong&gt; browses available courses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin&lt;/strong&gt; manages courses&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Student selects course → payment gateway integration → enrollment confirmation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Admin can approve or reject course creation requests&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;System should handle &lt;strong&gt;payment failure cases&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🛤️ Step-by-Step Walkthrough
&lt;/h2&gt;




&lt;h3&gt;
  
  
  Step 1: Write a Detailed System Description
&lt;/h3&gt;

&lt;p&gt;Before jumping into tools, clearly understand what you want to visualize. Draft a &lt;strong&gt;logical description&lt;/strong&gt; of how the system components interact. This involves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analyzing the source: For example, a source-code, pseudocode, or algorithm.&lt;/li&gt;
&lt;li&gt;Writing a short description: Explain the logic or flow in simple language.&lt;/li&gt;
&lt;li&gt;Identifying elements: Note down components like processes, inputs/outputs, functions, or actors that should be part of the diagram.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📌 Tip: This step can be manual or done in collaboration with AI by summarizing the core logic of your code/process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description Example:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Student browses available courses.&lt;/li&gt;
&lt;li&gt;Student selects a course → proceeds to payment.&lt;/li&gt;
&lt;li&gt;System connects to Payment Gateway API.&lt;/li&gt;
&lt;li&gt;If payment is successful → student enrollment confirmed.&lt;/li&gt;
&lt;li&gt;If payment fails → show error and retry option.&lt;/li&gt;
&lt;li&gt;Admin manages course creation, edits, deletions.&lt;/li&gt;
&lt;li&gt;Admin can approve/reject newly created course entries.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 2: Ask Claude to Generate draw.io XML Code
&lt;/h3&gt;

&lt;p&gt;Once you have the logical structure ready, use a detailed prompt to ask Claude AI to generate an XML-based diagram compatible with draw.io.&lt;br&gt;
Claude AI is better at generating longer, cleaner code blocks compared to ChatGPT.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Claude Prompt:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;


&lt;p&gt;“Generate draw.io-compatible XML code for a system flow diagram of an Online Course Registration System.&lt;br&gt;
Show entities like Student, Admin, Payment Gateway.&lt;br&gt;
Include success/failure flows and Admin approval flows clearly.&lt;br&gt;
Arrange elements logically and label all edges. The diagram should be visually appealing. The flow is like this-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Student browses available courses.&lt;/li&gt;
&lt;li&gt;Student selects a course → proceeds to payment.&lt;/li&gt;
&lt;li&gt;System connects to Payment Gateway API.&lt;/li&gt;
&lt;li&gt;If payment is successful → student enrollment confirmed.&lt;/li&gt;
&lt;li&gt;If payment fails → show error and retry option.&lt;/li&gt;
&lt;li&gt;Admin manages course creation, edits, deletions.&lt;/li&gt;
&lt;li&gt;Admin can approve/reject newly created course entries.”&lt;/li&gt;
&lt;/ol&gt;


&lt;/blockquote&gt;

&lt;p&gt;🎯 Claude responds with a complete XML.&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%2Fj0sbi78qhyl5kijhs89z.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%2Fj0sbi78qhyl5kijhs89z.png" alt="Claude’s output showing XML code" width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Tip: You can even provide entire source code, if it is single file. Claude will automatically figure out the flow of program.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 3: Create and Save the &lt;code&gt;.drawio&lt;/code&gt; File
&lt;/h3&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy the XML output.&lt;/li&gt;
&lt;li&gt;Open a text editor.&lt;/li&gt;
&lt;li&gt;Paste XML content.&lt;/li&gt;
&lt;li&gt;Save as:
📝 &lt;code&gt;course_flow.drawio&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Fjj3lcza8hc21o30dza6z.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%2Fjj3lcza8hc21o30dza6z.png" alt="Saving XML as a  raw `.drawio` endraw  file." width="800" height="747"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⚠️ Make sure to select &lt;strong&gt;All Files&lt;/strong&gt; type when saving.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 4: Import into draw.io
&lt;/h3&gt;

&lt;p&gt;There are two ways to do this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Via Web App:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://app.diagrams.net/" rel="noopener noreferrer"&gt;https://app.diagrams.net/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Device → Open Existing Diagram&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select your &lt;code&gt;.drawio&lt;/code&gt; file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ Your system diagram should now appear automatically!&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%2F3vx8i3ji0kk12wa6z4qu.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%2F3vx8i3ji0kk12wa6z4qu.png" alt="Importing  raw `.drawio` endraw  file into draw.io" width="800" height="593"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Via Desktop App:&lt;/strong&gt; If you have the draw.io desktop application installed, simply open the file using it.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 5: Manual Adjustments for Visual Appeal
&lt;/h3&gt;

&lt;p&gt;The imported diagram often needs cleanup for a &lt;strong&gt;professional look&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Align&lt;/strong&gt; boxes horizontally and vertically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Color-code&lt;/strong&gt; actors (Student, Admin, Payment Gateway)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Label&lt;/strong&gt; edges (e.g., "If Payment Fails", "Admin Approves")&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use consistent shape sizing&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&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%2Fso8md0bsugf1rsdeqgen.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%2Fso8md0bsugf1rsdeqgen.png" alt="After manually adjusting the layout" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎨 &lt;strong&gt;Design Tips&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use different shapes for different entity types (rectangles for processes, diamonds for decisions).&lt;/li&gt;
&lt;li&gt;Stick to 2–3 soft colors (sky blue, light green, soft grey).&lt;/li&gt;
&lt;li&gt;Leave good spacing between elements.&lt;/li&gt;
&lt;li&gt;Add a plain rectangle as a background, to enable appropriate exporting of complete image(as png/jpg etc).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 6: Export the Final Diagram
&lt;/h3&gt;

&lt;p&gt;Once finalized:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;File → Export As → PNG / PDF&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Enable "Include a copy of my diagram" for backup.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;high resolution&lt;/strong&gt; for better quality.&lt;/li&gt;
&lt;/ul&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%2F7mi8snapblrcznwcng23.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%2F7mi8snapblrcznwcng23.png" alt="Image description" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Final Result
&lt;/h2&gt;

&lt;p&gt;✅ A &lt;strong&gt;professional system diagram&lt;/strong&gt; ready for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project documentation&lt;/li&gt;
&lt;li&gt;Presentations&lt;/li&gt;
&lt;li&gt;Freelance portfolios&lt;/li&gt;
&lt;li&gt;Technical blogs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ Notes on AI Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Code Length: ChatGPT has a limit on how much XML code it can generate. For complex or very large diagrams, consider alternatives like Claude AI, which can handle longer outputs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Split Diagrams: For large systems, divide the diagram into smaller parts and generate/import them separately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verification: Always cross-check the logic and flow; AI may introduce small inconsistencies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Extra Bonus Tip: What to Do Next?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;💬 Add internal comments inside draw.io diagrams&lt;/li&gt;
&lt;li&gt;🔄 Use this workflow for &lt;strong&gt;ER diagrams, UMLs, flowcharts, API flows&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>ai</category>
      <category>architecture</category>
      <category>softwareengineering</category>
      <category>diagram</category>
    </item>
  </channel>
</rss>
