<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rohan Mhadgut</title>
    <description>The latest articles on DEV Community by Rohan Mhadgut (@rohan_mhadgut_10).</description>
    <link>https://dev.to/rohan_mhadgut_10</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%2F3503282%2Fb26fc619-83cd-4a38-9a9c-f649578d70fa.jpg</url>
      <title>DEV Community: Rohan Mhadgut</title>
      <link>https://dev.to/rohan_mhadgut_10</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rohan_mhadgut_10"/>
    <language>en</language>
    <item>
      <title>Why IoC and DI feel the same, but are actually not</title>
      <dc:creator>Rohan Mhadgut</dc:creator>
      <pubDate>Tue, 30 Sep 2025 13:37:21 +0000</pubDate>
      <link>https://dev.to/rohan_mhadgut_10/why-ioc-and-di-feel-the-same-but-are-actually-not-30kl</link>
      <guid>https://dev.to/rohan_mhadgut_10/why-ioc-and-di-feel-the-same-but-are-actually-not-30kl</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I first started learning Spring, I came across the concepts of Inversion of Control (IoC) and Dependency Injection (DI). The instructor explained the definitions, but to me, they sounded almost identical. If they really meant the same thing, why were there two different names? That question stuck with me. I started digging, browsing blogs, Stack Overflow, and Reddit, but I kept seeing answers that mixed up the two concepts and often called DI IoC. Like in this StackOverflow &lt;a href="https://stackoverflow.com/questions/3058/what-is-inversion-of-control" rel="noopener noreferrer"&gt;question&lt;/a&gt;, you could find many answers that mix up IoC with DI. After a bit more research and watching some really insightful YouTube explanations, I finally found clear, concrete definitions and the fundamental differences between IoC and DI. In this blog, I will share what I learned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Life With Too Many Responsibilities:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To understand why Inversion of Control is useful, let’s look at some real-world examples.&lt;/p&gt;

&lt;p&gt;Imagine a freelance website designer working alone. They have to find clients, manage billing, schedule meetings, design websites, handle updates, and deal with support requests. While it is possible to do everything, it quickly becomes exhausting and inefficient. There is little room to focus on the creative work, and every small task adds friction.&lt;/p&gt;

&lt;p&gt;Consider one more example. Think about a busy restaurant kitchen. Without help, the head chef would have to take orders, cook every dish, clean up, restock ingredients, and even deliver food to tables. It is possible, but the chef would quickly be overwhelmed, and the quality of the food and service would suffer.&lt;/p&gt;

&lt;p&gt;In both cases, the problem is the same: &lt;strong&gt;doing everything yourself leaves you overwhelmed and slows down progress&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But what if we could delegate these responsibilities to someone else? What if we could find someone who could do all the dirty work for us? What if we could just &lt;strong&gt;invert the control&lt;/strong&gt;?&lt;/p&gt;

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

&lt;p&gt;Well, it is in the name itself: IoC stands for Inversion of Control. (I know, you probably already know that, and you are not here just for the full form.)&lt;/p&gt;

&lt;p&gt;Let’s make it simpler.&lt;/p&gt;

&lt;p&gt;IoC is like saying: “I don’t want to do this task anymore. From now on, it’s your responsibility.”&lt;/p&gt;

&lt;p&gt;To visualize it, imagine a basketball team. The star player focuses on scoring points, but there is a teammate who dives for rebounds, hustles for every loose ball, defends aggressively, and takes the hits that nobody sees, someone like a Dennis Rodman or Draymond Green type of player. The star player does not have to worry about all of this because someone else is handling the gritty work. That teammate is like IoC in programming, taking care of the behind-the-scenes tasks so the main logic can shine.&lt;/p&gt;

&lt;p&gt;Or think of a busy restaurant kitchen. The head chef focuses on creating amazing dishes while assistants prep ingredients, manage orders, and serve food. The chef still decides what should be cooked, but they do not have to manage every single detail. IoC works the same way, delegating the repetitive or logistical tasks to someone else, allowing the important work to get done efficiently.&lt;/p&gt;

&lt;p&gt;A more technical way of explaining IoC would be: "Developers should keep their business logic clean by externalizing complicated and complex configuration, lifecycle management, and system interactions. Complex tasks should be handled by an IOC framework." (I got this definition from &lt;a href="https://youtu.be/FHii0xjGN5g?si=qew5LXWfd2un5Iyq" rel="noopener noreferrer"&gt;this&lt;/a&gt; YouTube video. Do check it out to get a better understanding of both the terms of IoC and DI)&lt;/p&gt;

&lt;p&gt;IoC appears in many software scenarios. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spring Framework automatically manages object creation and wiring for you.&lt;/li&gt;
&lt;li&gt;React handles rendering flows and updates your UI based on state changes.&lt;/li&gt;
&lt;li&gt;Event loops and callbacks in Node.js or GUI applications invert control, letting your code react to events rather than control the execution sequence directly. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of your code dictating every step, &lt;strong&gt;the framework or system takes over the flow&lt;/strong&gt;. You provide the instructions, what should happen, and the framework decides when and how it will happen.&lt;/p&gt;

&lt;p&gt;This is what makes life easier for developers. Just like the solo freelance designer or the overwhelmed chef, without IoC, you would be managing everything yourself. With IoC, you can hand off the repetitive, messy tasks and focus on what really matters.&lt;/p&gt;

&lt;p&gt;One of the most common ways this is done in software is through Dependency Injection, which we will explore next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You must have never thought, but even this is IoC:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before moving to the part of DI, I would like to share an interesting example of IoC that even I didn't think of, and maybe most of you as well.&lt;/p&gt;

&lt;p&gt;In your universities, colleges, or programming bootcamps, you must have learn a programming language like Java, Python, or JavaScript. In these programming tutorials, you must have designed some user input-based programs running on terminals that look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please enter your name
accept the name
Please enter your password
accept the password
check user exists
Log in the user
etc....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in the above scenario, &lt;strong&gt;you are controlling the flow of the program and not the user&lt;/strong&gt;. As you decide what the next step the user would be doing.&lt;/p&gt;

&lt;p&gt;Now, when you add a GUI for the same example above it would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;When the user types in the username field, store it in USERNAME
When the user types in the password field, store it in PASSWORD
When the user clicks on the login button, call the database to check if the user exists 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now &lt;strong&gt;control is inverted&lt;/strong&gt;... instead of the computer accepting user input in a fixed order, &lt;strong&gt;the user controls the order in which the data is entered&lt;/strong&gt;, and when the data is saved in the database.&lt;/p&gt;

&lt;p&gt;You can find the reference for the above example over &lt;a href="https://stackoverflow.com/a/3108" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Dependency Injection, or DI, is one of the most common ways that Inversion of Control is applied in software. If IoC is about handing off control of tasks, &lt;strong&gt;DI is about handing you exactly what you need to do your job&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine basketball again. The star player needs the ball to score. Instead of running across the court to fetch it every time, a teammate passes it directly to them at the perfect moment. That is DI. The ball is a dependency, and it is being injected at the right time so the star can focus on scoring.&lt;/p&gt;

&lt;p&gt;In real life, think of a freelance website designer. Instead of spending hours finding clients, sending invoices, and setting up meetings, they have an assistant who handles these tasks. The designer still does the creative work of building websites, but the assistant provides the resources and support exactly when needed. That is Dependency Injection at work.&lt;/p&gt;

&lt;p&gt;In software, DI allows your objects or components to receive the dependencies they need from an external source rather than creating them themselves. This makes your code cleaner, easier to maintain, and much simpler to test. You focus on your core work while the framework or system provides all the supporting pieces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Examples of IoC and DI using Spring:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example of Freelancer doing everything without IoC and DI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Freelancer {
    private Billing billing = new Billing();
    private ClientFinder clientFinder = new ClientFinder();
    private MeetingScheduler meetingScheduler = new MeetingScheduler();

    void work() {
        clientFinder.findClients();
        meetingScheduler.schedule();
        billing.sendInvoice();
        System.out.println("Designing website...");
    }
}

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

&lt;/div&gt;



&lt;p&gt;Here, the Freelancer class creates and manages everything. Just like the freelance designer in our earlier example, this class is overwhelmed because it has to handle all the responsibilities itself.&lt;/p&gt;

&lt;p&gt;Example of Freelancer with IoC and DI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// IoC Example: By adding @Component, we tell Spring to manage the object lifecycle for us. 
// Spring will create, configure, and destroy these objects when needed.
@Component
class Billing {
    void sendInvoice() {
        System.out.println("Invoice sent");
    }
}

@Component
class ClientFinder {
    void findClients() {
        System.out.println("Clients found");
    }
}

@Component
class MeetingScheduler {
    void schedule() {
        System.out.println("Meeting scheduled");
    }
}

@Component
class Freelancer {
    private final Billing billing;
    private final ClientFinder clientFinder;
    private final MeetingScheduler meetingScheduler;

    // DI Example: By adding @Autowired, we ask Spring to provide the required dependencies. 
    // Spring injects Billing, ClientFinder, and MeetingScheduler into Freelancer automatically.
    @Autowired
    Freelancer(Billing billing, ClientFinder clientFinder, MeetingScheduler meetingScheduler) {
        this.billing = billing;
        this.clientFinder = clientFinder;
        this.meetingScheduler = meetingScheduler;
    }

    void work() {
        clientFinder.findClients();
        meetingScheduler.schedule();
        billing.sendInvoice();
        System.out.println("Designing website...");
    }
}

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

&lt;/div&gt;



&lt;p&gt;Now the Freelancer no longer creates Billing, ClientFinder, or MeetingScheduler. Instead, Spring handles all of that (IoC), and just passes them in (DI). The Freelancer can now focus on the actual creative work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summarizing the difference:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is easy to confuse Inversion of Control and Dependency Injection because they are closely related. Both involve someone else taking care of work you would normally do, but they are not the same.&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%2F49an9dtw0z8qsaq9hk34.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%2F49an9dtw0z8qsaq9hk34.png" alt=" " width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In short, all DI is IoC, because the control of providing dependencies is inverted. But not all IoC is DI, because IoC can also refer to things like event loops, callbacks, or framework-managed flows where no dependencies are being injected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion / Takeaway:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Understanding Inversion of Control and Dependency Injection is more than just a technical detail. These concepts change the way you think about building software. By letting frameworks handle the repetitive, logistical, or timing-sensitive tasks, you can focus on solving real problems instead of wrestling with object creation, wiring, or flow management.&lt;/p&gt;

&lt;p&gt;IoC and DI also make your code more flexible and easier to maintain. You can swap implementations, add new features, or test components in isolation without breaking the rest of your system. This is why modern frameworks rely heavily on these principles. They are not just conveniences, they are tools for writing scalable, robust, and clean software.&lt;/p&gt;

&lt;p&gt;In short, mastering IoC and DI is like learning to delegate effectively in real life. Once you embrace this mindset, both coding and designing systems become less about doing everything yourself and more about orchestrating the right pieces to work together efficiently.&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>designpatterns</category>
      <category>architecture</category>
    </item>
    <item>
      <title>My understanding of microservices was totally wrong</title>
      <dc:creator>Rohan Mhadgut</dc:creator>
      <pubDate>Mon, 29 Sep 2025 06:15:16 +0000</pubDate>
      <link>https://dev.to/rohan_mhadgut_10/my-understanding-of-microservices-was-totally-wrong-j9</link>
      <guid>https://dev.to/rohan_mhadgut_10/my-understanding-of-microservices-was-totally-wrong-j9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I have been building CRUD applications for a long time, during my previous job, internships, and university assignments.&lt;/p&gt;

&lt;p&gt;In a typical CRUD application, your project is divided into three major components.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Front-end&lt;/strong&gt;: Built using HTML, CSS, JavaScript, and frameworks or libraries like React, Angular, or Vue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Back-end&lt;/strong&gt;: APIs built using Java with Spring Boot, Python with Django or Flask, or Node.js and Express.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Database&lt;/strong&gt;: Where all data is stored and retrieved, using SQL databases such as MySQL or PostgreSQL, or NoSQL options like MongoDB.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This structure is often called a 3-Tier Architecture because the application is basically divided into three layers: frontend, backend, and database.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Assumption About Microservices
&lt;/h2&gt;

&lt;p&gt;Eventually, I learned about Microservices architecture, or at least I thought I did. To me, a microservice was simply a service running independently and communicating with others using REST APIs. This assumption led me to believe that if I ran my frontend, backend, and database inside Docker containers and made them communicate via REST, I was actually building a microservices-based application.&lt;/p&gt;

&lt;p&gt;I even built such an application using Java Spring Boot, React, and MySQL, which you can check out at : &lt;a href="https://github.com/Ron1005/ERP" rel="noopener noreferrer"&gt;Building a Full-stack ERP&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Monolithic Architecture
&lt;/h2&gt;

&lt;p&gt;While studying Microservices architecture again, I realized I was completely wrong. What I had built was still based on a Monolithic Architecture and not microservices.&lt;/p&gt;

&lt;p&gt;In a Monolithic Architecture, the frontend, backend, and database all live in a single codebase and are tightly coupled. This makes it easy to get started, but as the application grows, it becomes difficult to scale, maintain, and deploy safely.&lt;/p&gt;

&lt;p&gt;In this type of application, different teams, such as the Accounts Dev Team, Loans Dev Team, Cards Dev Team, and the UI/UX Dev Team, push their updates to the same codebase. The code is then built using tools like Jenkins and deployed to a single server, which means that even small changes affect the entire application.&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%2Frdv8uujxk683cuhcckjq.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%2Frdv8uujxk683cuhcckjq.png" alt="Flow Diagram of Monolith Architecture" width="784" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can think of a monolithic application like a Jenga tower. All the blocks are stacked together, and each one depends on the others for stability. If you remove or change just one block, for example, a part of the backend or database, the entire application could break, just like the tower collapsing. This shows why monolithic apps are fragile and harder to scale as they grow&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Thought My 3-Tier App Was a Microservice
&lt;/h2&gt;

&lt;p&gt;For the longest time, I believed my 3-tier CRUD apps were microservices. On the surface, it looked like I had independent services. There was a frontend running in React, a backend API layer in Spring Boot, and a MySQL database. Each layer ran in its own Docker container, communicating with the others through REST APIs. To me, this seemed like the perfect example of microservices in action.&lt;/p&gt;

&lt;p&gt;Looking back, I feel like a dumbass. I had confused containers and APIs with true microservices. &lt;strong&gt;Just because something runs separately in Docker does not mean it is independently deployable or truly independent&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Microservices?
&lt;/h2&gt;

&lt;p&gt;A microservices architecture is a way of building applications as a collection of small, independent services, each &lt;strong&gt;responsible for a single feature or business capability&lt;/strong&gt;. Each service:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Has its own codebase and can be deployed independently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can have its own database or data storage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Communicates with other services through APIs or messaging systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can be built using different technologies depending on what fits best.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a microservices architecture, different teams such as the Accounts Dev Team, Loans Dev Team, Cards Dev Team, and the UI/UX Dev Team each own their own independent service and codebase. Each team can build, test, and deploy their service without waiting for others. These services are usually deployed in containers or cloud environments, often with their own databases, and communicate with other services using APIs or messaging systems. This means that small changes in one service do not require redeploying the entire application, and updates can be rolled out more frequently and independently.&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%2Fkim40sxc9lhlfgdgp2wd.jpg" 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%2Fkim40sxc9lhlfgdgp2wd.jpg" alt="Flow chart of a Microservices Architecture" width="800" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think of it like a team of specialized chefs in a restaurant. Each chef focuses on a single dish and can cook independently. If the pastry chef is busy, the rest of the kitchen can still function. In contrast, a monolithic app is like one chef trying to cook all dishes at the same time; if they get sick, the whole restaurant suffers.&lt;/p&gt;

&lt;p&gt;Microservices make applications more scalable, resilient, and easier to maintain at large scale, but they also introduce extra complexity, like communication between services and monitoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why My 3-Tier App Was Still Monolithic
&lt;/h2&gt;

&lt;p&gt;Even though I had three separate layers, my application was still monolithic because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All the backend logic lived in a single codebase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The frontend, backend, and database were tightly coupled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If one part failed, it could affect the whole system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any schema changes in the database or major updates in the backend could break other parts of the application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scaling was limited. I could scale the backend as a whole, but I could not scale individual features or services independently.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In contrast, microservices allow you to scale each service based on its own needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Difference
&lt;/h2&gt;

&lt;p&gt;Here is a small table that will help you differentiate between Monolithic and Microservices Architecture:&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%2F7hf9tc7rri93br7a5n1p.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%2F7hf9tc7rri93br7a5n1p.png" alt="Difference between Monolithic and Microservices" width="800" height="610"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A true microservice is independently deployable, owns its own data, and communicates with other services via APIs. One service can fail, be updated, or scaled without affecting the others. My 3-tier apps, no matter how nicely divided into frontend, backend, and database layers, were still a single, unified application. &lt;strong&gt;They were layered, not independent&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Simple Thumb Rule
&lt;/h2&gt;

&lt;p&gt;If it scales and deploys as one unit, it’s monolithic. If it scales and deploys in parts, it’s microservices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;The words layers and services can be confusing. The important lesson is understanding the difference now and knowing that separation alone does not make an application a microservice. Running things in Docker and communicating via APIs is useful, but it does not automatically make your app a microservice.&lt;/p&gt;

&lt;p&gt;The real takeaway is that learning architecture is a journey. Mistakes like this are part of the process, and understanding them makes you a better developer. At the same time, it is worth remembering that microservices are not perfect either. They introduce added complexity with service-to-service communication, monitoring, testing, and deployment pipelines. Choosing between monolithic and microservices should always depend on the scale and needs of the application.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
