<?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: Khairul Basar</title>
    <description>The latest articles on DEV Community by Khairul Basar (@khairul_basar_a2746d66c5f).</description>
    <link>https://dev.to/khairul_basar_a2746d66c5f</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%2F3718727%2F0f123384-37d9-409f-936b-3d4eefcbeed3.webp</url>
      <title>DEV Community: Khairul Basar</title>
      <link>https://dev.to/khairul_basar_a2746d66c5f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/khairul_basar_a2746d66c5f"/>
    <language>en</language>
    <item>
      <title>Monolith vs Modular Monolith vs Multi-Module vs Microservices in Spring Boot</title>
      <dc:creator>Khairul Basar</dc:creator>
      <pubDate>Tue, 17 Feb 2026 06:02:46 +0000</pubDate>
      <link>https://dev.to/khairul_basar_a2746d66c5f/monolith-vs-modular-monolith-vs-multi-module-vs-microservices-in-spring-boot-5f8h</link>
      <guid>https://dev.to/khairul_basar_a2746d66c5f/monolith-vs-modular-monolith-vs-multi-module-vs-microservices-in-spring-boot-5f8h</guid>
      <description>&lt;p&gt;🏗 Monolith vs Modular Monolith vs Multi-Module vs Microservices in Spring Boot&lt;br&gt;
A Complete Beginner-Friendly Guide with Real Hospital System Example&lt;br&gt;
📚 Introduction&lt;br&gt;
Building a backend system with Spring Boot is exciting, but every developer faces the same crucial question:&lt;/p&gt;

&lt;p&gt;"Which architecture style should I choose for my project?"&lt;/p&gt;

&lt;p&gt;The answer isn't always straightforward. Should you build everything in one place? Split into modules? Go fully distributed with microservices?&lt;/p&gt;

&lt;p&gt;In this comprehensive guide, we'll explore four different architecture styles using a real-world example:&lt;/p&gt;

&lt;p&gt;🏥 Hospital OPD Appointment &amp;amp; Billing System&lt;br&gt;
Our system will handle:&lt;/p&gt;

&lt;p&gt;Identity Module - Login, registration, user management&lt;/p&gt;

&lt;p&gt;Doctor Management - Doctor profiles, schedules, specializations&lt;/p&gt;

&lt;p&gt;Appointment Booking - Slot booking, availability checking&lt;/p&gt;

&lt;p&gt;Billing - Invoice generation, payment processing&lt;/p&gt;

&lt;p&gt;Notification - SMS/Email alerts for appointments&lt;/p&gt;

&lt;p&gt;We'll implement this same system in four different ways and understand:&lt;/p&gt;

&lt;p&gt;How each architecture works&lt;/p&gt;

&lt;p&gt;How modules communicate&lt;/p&gt;

&lt;p&gt;Step-by-step implementation details&lt;/p&gt;

&lt;p&gt;Pros and cons of each approach&lt;/p&gt;

&lt;p&gt;When to use which architecture&lt;/p&gt;

&lt;p&gt;🎯 Understanding the Problem Domain&lt;br&gt;
Before diving into architectures, let's understand our hospital system requirements:&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Core business requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Patients can register and login&lt;/li&gt;
&lt;li&gt;Patients can view available doctors&lt;/li&gt;
&lt;li&gt;Patients can book appointments&lt;/li&gt;
&lt;li&gt;System sends confirmation notifications&lt;/li&gt;
&lt;li&gt;Billing generates invoice after appointment&lt;/li&gt;
&lt;li&gt;Doctors can manage their schedules
Each module has specific responsibilities, and they need to work together seamlessly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1️⃣ MONOLITH ARCHITECTURE&lt;br&gt;
The Traditional Approach&lt;br&gt;
🔍 What is a Monolith?&lt;br&gt;
A monolithic architecture means everything lives inside ONE Spring Boot application. Think of it as a single, unified codebase where all modules - Identity, Doctor, Appointment, Billing, and Notification - coexist in the same project.&lt;/p&gt;

&lt;p&gt;🏢 Real-Life Analogy&lt;br&gt;
Imagine a single hospital building where:&lt;/p&gt;

&lt;p&gt;Reception desk (Identity)&lt;/p&gt;

&lt;p&gt;Doctor's chambers (Doctor Management)&lt;/p&gt;

&lt;p&gt;Appointment desk (Booking)&lt;/p&gt;

&lt;p&gt;Billing counter (Billing)&lt;/p&gt;

&lt;p&gt;Communication center (Notification)&lt;/p&gt;

&lt;p&gt;All departments are in the same building. Staff can walk between departments easily. That's your monolith!&lt;/p&gt;

&lt;p&gt;📦 Detailed Project Structure&lt;br&gt;
text&lt;br&gt;
opd-system/&lt;br&gt;
├── src/&lt;br&gt;
│   ├── main/&lt;br&gt;
│   │   ├── java/&lt;br&gt;
│   │   │   └── com/&lt;br&gt;
│   │   │       └── hospital/&lt;br&gt;
│   │   │           └── opd/&lt;br&gt;
│   │   │               ├── OpdApplication.java&lt;br&gt;
│   │   │               │&lt;br&gt;
│   │   │               ├── controller/&lt;br&gt;
│   │   │               │   ├── AuthController.java&lt;br&gt;
│   │   │               │   ├── DoctorController.java&lt;br&gt;
│   │   │               │   ├── AppointmentController.java&lt;br&gt;
│   │   │               │   ├── BillingController.java&lt;br&gt;
│   │   │               │   └── NotificationController.java&lt;br&gt;
│   │   │               │&lt;br&gt;
│   │   │               ├── service/&lt;br&gt;
│   │   │               │   ├── UserService.java&lt;br&gt;
│   │   │               │   ├── DoctorService.java&lt;br&gt;
│   │   │               │   ├── AppointmentService.java&lt;br&gt;
│   │   │               │   ├── BillingService.java&lt;br&gt;
│   │   │               │   └── NotificationService.java&lt;br&gt;
│   │   │               │&lt;br&gt;
│   │   │               ├── repository/&lt;br&gt;
│   │   │               │   ├── UserRepository.java&lt;br&gt;
│   │   │               │   ├── DoctorRepository.java&lt;br&gt;
│   │   │               │   ├── AppointmentRepository.java&lt;br&gt;
│   │   │               │   ├── BillingRepository.java&lt;br&gt;
│   │   │               │   └── NotificationRepository.java&lt;br&gt;
│   │   │               │&lt;br&gt;
│   │   │               ├── entity/&lt;br&gt;
│   │   │               │   ├── User.java&lt;br&gt;
│   │   │               │   ├── Doctor.java&lt;br&gt;
│   │   │               │   ├── Appointment.java&lt;br&gt;
│   │   │               │   ├── Bill.java&lt;br&gt;
│   │   │               │   └── Notification.java&lt;br&gt;
│   │   │               │&lt;br&gt;
│   │   │               └── config/&lt;br&gt;
│   │   │                   ├── SecurityConfig.java&lt;br&gt;
│   │   │                   └── SwaggerConfig.java&lt;br&gt;
│   │   │&lt;br&gt;
│   │   └── resources/&lt;br&gt;
│   │       ├── application.properties&lt;br&gt;
│   │       └── db/&lt;br&gt;
│   │           └── migration/&lt;br&gt;
│   │&lt;br&gt;
│   └── test/&lt;br&gt;
│       └── java/&lt;br&gt;
│           └── com/&lt;br&gt;
│               └── hospital/&lt;br&gt;
│                   └── opd/&lt;br&gt;
│                       ├── service/&lt;br&gt;
│                       └── controller/&lt;br&gt;
🔄 How Modules Communicate in Monolith&lt;br&gt;
In a monolith, communication is direct and simple - just Java method calls!&lt;/p&gt;

&lt;p&gt;Example: Booking an Appointment&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
@Service&lt;br&gt;
public class AppointmentService {&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Autowired
private DoctorService doctorService;

@Autowired
private UserService userService;

@Autowired
private NotificationService notificationService;

@Autowired
private BillingService billingService;

@Transactional
public Appointment bookAppointment(AppointmentRequest request) {
    // 1. Verify doctor availability (direct method call)
    Doctor doctor = doctorService.findAvailableDoctor(
        request.getDoctorId(), 
        request.getDateTime()
    );

    // 2. Get patient details (direct method call)
    User patient = userService.findById(request.getPatientId());

    // 3. Create appointment
    Appointment appointment = new Appointment();
    appointment.setDoctor(doctor);
    appointment.setPatient(patient);
    appointment.setDateTime(request.getDateTime());
    appointment.setStatus(Status.CONFIRMED);

    appointment = appointmentRepository.save(appointment);

    // 4. Generate bill (direct method call)
    Bill bill = billingService.createBill(appointment);

    // 5. Send notification (direct method call)
    notificationService.sendAppointmentConfirmation(
        patient.getEmail(), 
        appointment
    );

    return appointment;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
Notice: No HTTP calls, no message queues, no network communication. Just plain Java method calls within the same JVM.&lt;/p&gt;

&lt;p&gt;🧩 Architecture Diagram&lt;br&gt;
text&lt;br&gt;
                    ┌─────────────────────────────────────┐&lt;br&gt;
                    │         OPD MONOLITH APP            │&lt;br&gt;
                    │         (Single JVM)                 │&lt;br&gt;
                    │                                       │&lt;br&gt;
                    │  ┌─────────────────────────────────┐ │&lt;br&gt;
                    │  │       CONTROLLER LAYER          │ │&lt;br&gt;
                    │  │  Auth  Doctor  Appt  Bill  Notif│ │&lt;br&gt;
                    │  └───────────────┬─────────────────┘ │&lt;br&gt;
                    │                  │                    │&lt;br&gt;
                    │  ┌───────────────▼─────────────────┐ │&lt;br&gt;
                    │  │         SERVICE LAYER            │ │&lt;br&gt;
                    │  │  Auth  Doctor  Appt  Bill  Notif│ │&lt;br&gt;
                    │  └───────────────┬─────────────────┘ │&lt;br&gt;
                    │                  │                    │&lt;br&gt;
                    │  ┌───────────────▼─────────────────┐ │&lt;br&gt;
                    │  │        REPOSITORY LAYER          │ │&lt;br&gt;
                    │  │  Auth  Doctor  Appt  Bill  Notif│ │&lt;br&gt;
                    │  └───────────────┬─────────────────┘ │&lt;br&gt;
                    │                  │                    │&lt;br&gt;
                    │  ┌───────────────▼─────────────────┐ │&lt;br&gt;
                    │  │          ENTITY LAYER            │ │&lt;br&gt;
                    │  │  User  Doctor  Appt  Bill  Notif│ │&lt;br&gt;
                    │  └─────────────────────────────────┘ │&lt;br&gt;
                    └─────────────────┬───────────────────┘&lt;br&gt;
                                      │&lt;br&gt;
                            ┌─────────▼─────────┐&lt;br&gt;
                            │   PostgreSQL DB   │&lt;br&gt;
                            │   (Single Schema)  │&lt;br&gt;
                            └───────────────────┘&lt;br&gt;
💻 Code Walkthrough: Monolith Implementation&lt;br&gt;
Application Properties:&lt;/p&gt;

&lt;p&gt;properties&lt;/p&gt;
&lt;h1&gt;
  
  
  application.properties
&lt;/h1&gt;

&lt;p&gt;spring.datasource.url=jdbc:postgresql://localhost:5432/opd_db&lt;br&gt;
spring.datasource.username=admin&lt;br&gt;
spring.datasource.password=password&lt;br&gt;
spring.jpa.hibernate.ddl-auto=update&lt;br&gt;
spring.jpa.show-sql=true&lt;br&gt;
Entity Example:&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/entity"&gt;@entity&lt;/a&gt;&lt;br&gt;
@Table(name = "appointments")&lt;br&gt;
public class Appointment {&lt;br&gt;
    &lt;a class="mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt;&lt;br&gt;
    @GeneratedValue(strategy = GenerationType.IDENTITY)&lt;br&gt;
    private Long id;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ManyToOne
@JoinColumn(name = "doctor_id")
private Doctor doctor;

@ManyToOne
@JoinColumn(name = "patient_id")
private User patient;

private LocalDateTime appointmentDateTime;
private String status;

@OneToOne(mappedBy = "appointment")
private Bill bill;

// getters, setters, constructors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
✅ Pros of Monolith&lt;br&gt;
Simple to Develop&lt;/p&gt;

&lt;p&gt;One codebase to manage&lt;/p&gt;

&lt;p&gt;Easy to understand for beginners&lt;/p&gt;

&lt;p&gt;Quick setup and configuration&lt;/p&gt;

&lt;p&gt;Easy Debugging&lt;/p&gt;

&lt;p&gt;Single log file&lt;/p&gt;

&lt;p&gt;No network issues to debug&lt;/p&gt;

&lt;p&gt;Clear stack traces&lt;/p&gt;

&lt;p&gt;Fast Communication&lt;/p&gt;

&lt;p&gt;Method calls are instant&lt;/p&gt;

&lt;p&gt;No network latency&lt;/p&gt;

&lt;p&gt;No serialization overhead&lt;/p&gt;

&lt;p&gt;Simple Deployment&lt;/p&gt;

&lt;p&gt;One JAR/WAR file&lt;/p&gt;

&lt;p&gt;One server to configure&lt;/p&gt;

&lt;p&gt;Easy to deploy anywhere&lt;/p&gt;

&lt;p&gt;Perfect for MVP&lt;/p&gt;

&lt;p&gt;Build fast&lt;/p&gt;

&lt;p&gt;Validate ideas quickly&lt;/p&gt;

&lt;p&gt;Iterate rapidly&lt;/p&gt;

&lt;p&gt;❌ Cons of Monolith&lt;br&gt;
Scaling Limitations&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Can't scale just the appointment module&lt;br&gt;
// Must scale entire application&lt;br&gt;
Code Organization Challenges&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// As code grows, dependencies become messy&lt;br&gt;
// Service classes might accidentally use each other's internals&lt;br&gt;
Team Development Bottlenecks&lt;/p&gt;

&lt;p&gt;Multiple teams working on same codebase&lt;/p&gt;

&lt;p&gt;Merge conflicts common&lt;/p&gt;

&lt;p&gt;Feature coordination overhead&lt;/p&gt;

&lt;p&gt;Technology Lock-in&lt;/p&gt;

&lt;p&gt;One technology stack for everything&lt;/p&gt;

&lt;p&gt;Can't use different databases for different modules&lt;/p&gt;

&lt;p&gt;One Failure Affects All&lt;/p&gt;

&lt;p&gt;If billing has memory leak, appointment booking fails too&lt;/p&gt;

&lt;p&gt;No fault isolation&lt;/p&gt;

&lt;p&gt;🎯 When to Use Monolith&lt;br&gt;
✅ Perfect for:&lt;/p&gt;

&lt;p&gt;Startups building MVP&lt;/p&gt;

&lt;p&gt;Small teams (2-5 developers)&lt;/p&gt;

&lt;p&gt;Simple applications with low complexity&lt;/p&gt;

&lt;p&gt;Learning projects&lt;/p&gt;

&lt;p&gt;Internal tools&lt;/p&gt;

&lt;p&gt;Projects with tight deadlines&lt;/p&gt;

&lt;p&gt;❌ Avoid when:&lt;/p&gt;

&lt;p&gt;Multiple teams are working independently&lt;/p&gt;

&lt;p&gt;You need to scale specific features&lt;/p&gt;

&lt;p&gt;System has high complexity&lt;/p&gt;

&lt;p&gt;You need technology diversity&lt;/p&gt;

&lt;p&gt;2️⃣ MODULAR MONOLITH (Spring Modulith)&lt;br&gt;
Structured Single Application&lt;br&gt;
🔍 What is a Modular Monolith?&lt;br&gt;
A Modular Monolith (or Modulith) is still ONE application, but internally divided into strict modules with clear boundaries. Each module has its own public API and hides its internal implementation.&lt;/p&gt;

&lt;p&gt;🏢 Real-Life Analogy&lt;br&gt;
Think of a modern hospital with secured departments:&lt;/p&gt;

&lt;p&gt;Each department (Identity, Doctor, Appointment) has its own entrance&lt;/p&gt;

&lt;p&gt;Departments communicate through formal channels&lt;/p&gt;

&lt;p&gt;Staff can't just walk into any department without proper authorization&lt;/p&gt;

&lt;p&gt;Each department has its own internal operations that others can't see&lt;/p&gt;

&lt;p&gt;📦 Detailed Project Structure with Spring Modulith&lt;br&gt;
text&lt;br&gt;
opd-modulith/&lt;br&gt;
├── src/&lt;br&gt;
│   └── main/&lt;br&gt;
│       └── java/&lt;br&gt;
│           └── com/&lt;br&gt;
│               └── hospital/&lt;br&gt;
│                   └── opd/&lt;br&gt;
│                       ├── OpdApplication.java&lt;br&gt;
│                       │&lt;br&gt;
│                       ├── identity/&lt;br&gt;
│                       │   ├── api/&lt;br&gt;
│                       │   │   ├── IdentityService.java (public interface)&lt;br&gt;
│                       │   │   └── dto/&lt;br&gt;
│                       │   │       ├── UserDTO.java&lt;br&gt;
│                       │   │       └── LoginRequest.java&lt;br&gt;
│                       │   ├── internal/&lt;br&gt;
│                       │   │   ├── model/&lt;br&gt;
│                       │   │   │   └── User.java (internal entity)&lt;br&gt;
│                       │   │   ├── repository/&lt;br&gt;
│                       │   │   │   └── UserRepository.java&lt;br&gt;
│                       │   │   └── service/&lt;br&gt;
│                       │   │       └── IdentityServiceImpl.java&lt;br&gt;
│                       │   └── events/&lt;br&gt;
│                       │       └── UserRegisteredEvent.java&lt;br&gt;
│                       │&lt;br&gt;
│                       ├── doctor/&lt;br&gt;
│                       │   ├── api/&lt;br&gt;
│                       │   │   ├── DoctorService.java&lt;br&gt;
│                       │   │   └── dto/&lt;br&gt;
│                       │   │       ├── DoctorDTO.java&lt;br&gt;
│                       │   │       └── AvailabilityDTO.java&lt;br&gt;
│                       │   ├── internal/&lt;br&gt;
│                       │   │   ├── model/&lt;br&gt;
│                       │   │   │   └── Doctor.java&lt;br&gt;
│                       │   │   ├── repository/&lt;br&gt;
│                       │   │   │   └── DoctorRepository.java&lt;br&gt;
│                       │   │   └── service/&lt;br&gt;
│                       │   │       └── DoctorServiceImpl.java&lt;br&gt;
│                       │   └── events/&lt;br&gt;
│                       │       └── DoctorAvailabilityChangedEvent.java&lt;br&gt;
│                       │&lt;br&gt;
│                       ├── appointment/&lt;br&gt;
│                       │   ├── api/&lt;br&gt;
│                       │   │   ├── AppointmentService.java&lt;br&gt;
│                       │   │   └── dto/&lt;br&gt;
│                       │   │       ├── AppointmentRequest.java&lt;br&gt;
│                       │   │       └── AppointmentDTO.java&lt;br&gt;
│                       │   ├── internal/&lt;br&gt;
│                       │   │   ├── model/&lt;br&gt;
│                       │   │   │   └── Appointment.java&lt;br&gt;
│                       │   │   ├── repository/&lt;br&gt;
│                       │   │   │   └── AppointmentRepository.java&lt;br&gt;
│                       │   │   └── service/&lt;br&gt;
│                       │   │       └── AppointmentServiceImpl.java&lt;br&gt;
│                       │   └── events/&lt;br&gt;
│                       │       └── AppointmentBookedEvent.java&lt;br&gt;
│                       │&lt;br&gt;
│                       ├── billing/&lt;br&gt;
│                       │   ├── api/&lt;br&gt;
│                       │   │   ├── BillingService.java&lt;br&gt;
│                       │   │   └── dto/&lt;br&gt;
│                       │   │       └── InvoiceDTO.java&lt;br&gt;
│                       │   ├── internal/&lt;br&gt;
│                       │   │   ├── model/&lt;br&gt;
│                       │   │   │   └── Bill.java&lt;br&gt;
│                       │   │   ├── repository/&lt;br&gt;
│                       │   │   │   └── BillingRepository.java&lt;br&gt;
│                       │   │   └── service/&lt;br&gt;
│                       │   │       └── BillingServiceImpl.java&lt;br&gt;
│                       │   └── events/&lt;br&gt;
│                       │       └── BillGeneratedEvent.java&lt;br&gt;
│                       │&lt;br&gt;
│                       └── notification/&lt;br&gt;
│                           ├── api/&lt;br&gt;
│                           │   ├── NotificationService.java&lt;br&gt;
│                           │   └── dto/&lt;br&gt;
│                           │       └── NotificationRequest.java&lt;br&gt;
│                           ├── internal/&lt;br&gt;
│                           │   ├── model/&lt;br&gt;
│                           │   │   └── Notification.java&lt;br&gt;
│                           │   ├── repository/&lt;br&gt;
│                           │   │   └── NotificationRepository.java&lt;br&gt;
│                           │   └── service/&lt;br&gt;
│                           │       └── NotificationServiceImpl.java&lt;br&gt;
│                           └── events/&lt;br&gt;
│                               └── NotificationSentEvent.java&lt;br&gt;
🔄 Communication in Modular Monolith&lt;br&gt;
Spring Modulith supports two communication patterns:&lt;/p&gt;

&lt;p&gt;Pattern 1: Controlled Direct Calls (via Public APIs)&lt;br&gt;
java&lt;br&gt;
// Identity Module - Public API&lt;br&gt;
package com.hospital.opd.identity.api;&lt;/p&gt;

&lt;p&gt;public interface IdentityService {&lt;br&gt;
    UserDTO findUserById(Long id);&lt;br&gt;
    UserDTO registerUser(RegisterRequest request);&lt;br&gt;
    boolean validateUserCredentials(String email, String password);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Identity Module - Internal Implementation&lt;br&gt;
package com.hospital.opd.identity.internal.service;&lt;/p&gt;

&lt;p&gt;@Service&lt;br&gt;
@Modulithic(module = "identity")&lt;br&gt;
class IdentityServiceImpl implements IdentityService {&lt;br&gt;
    @Autowired&lt;br&gt;
    private UserRepository userRepository;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
public UserDTO findUserById(Long id) {
    // Internal implementation hidden from other modules
    User user = userRepository.findById(id)
        .orElseThrow(() -&amp;gt; new UserNotFoundException(id));
    return mapToDTO(user);
}

private UserDTO mapToDTO(User user) {
    // Internal mapping logic
    return new UserDTO(user.getId(), user.getName(), user.getEmail());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Appointment Module using Identity Module&lt;br&gt;
package com.hospital.opd.appointment.api;&lt;/p&gt;

&lt;p&gt;@Service&lt;br&gt;
@Modulithic(module = "appointment")&lt;br&gt;
class AppointmentServiceImpl implements AppointmentService {&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Using public API, not internal implementation
@Autowired
private IdentityService identityService;

@Override
public AppointmentDTO bookAppointment(AppointmentRequest request) {
    // Can only access public methods
    UserDTO patient = identityService.findUserById(request.getPatientId());

    // Cannot access internal Identity classes!
    // identityService.userRepository.findById() ❌ Not accessible

    // Rest of the logic
    Appointment appointment = createAppointment(patient, request);
    return mapToDTO(appointment);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
Pattern 2: Event-Based Communication (Recommended)&lt;br&gt;
java&lt;br&gt;
// 1. Define Event in Appointment Module&lt;br&gt;
package com.hospital.opd.appointment.events;&lt;/p&gt;

&lt;p&gt;public class AppointmentBookedEvent {&lt;br&gt;
    private final Long appointmentId;&lt;br&gt;
    private final Long patientId;&lt;br&gt;
    private final Long doctorId;&lt;br&gt;
    private final LocalDateTime appointmentTime;&lt;br&gt;
    private final BigDecimal consultationFee;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// constructor, getters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// 2. Publish Event in Appointment Module&lt;br&gt;
package com.hospital.opd.appointment.internal.service;&lt;/p&gt;

&lt;p&gt;@Service&lt;br&gt;
@Modulithic(module = "appointment")&lt;br&gt;
class AppointmentServiceImpl implements AppointmentService {&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Autowired
private ApplicationEventPublisher eventPublisher;

@Override
@Transactional
public AppointmentDTO bookAppointment(AppointmentRequest request) {
    // 1. Create appointment
    Appointment appointment = createAppointment(request);

    // 2. Save to database
    appointment = appointmentRepository.save(appointment);

    // 3. Publish event - other modules will react
    eventPublisher.publishEvent(new AppointmentBookedEvent(
        appointment.getId(),
        appointment.getPatientId(),
        appointment.getDoctorId(),
        appointment.getDateTime(),
        appointment.getConsultationFee()
    ));

    return mapToDTO(appointment);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// 3. Billing Module Listens to Event&lt;br&gt;
package com.hospital.opd.billing.internal.service;&lt;/p&gt;

&lt;p&gt;@Service&lt;br&gt;
@Modulithic(module = "billing")&lt;br&gt;
class BillingEventListener {&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Autowired
private BillingService billingService;

@EventListener
@Transactional
public void handleAppointmentBooked(AppointmentBookedEvent event) {
    // Billing module reacts independently
    InvoiceDTO invoice = billingService.createInvoice(
        event.getAppointmentId(),
        event.getPatientId(),
        event.getConsultationFee()
    );

    // Can publish its own events
    eventPublisher.publishEvent(new BillGeneratedEvent(invoice));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// 4. Notification Module Listens to Multiple Events&lt;br&gt;
package com.hospital.opd.notification.internal.service;&lt;/p&gt;

&lt;p&gt;@Service&lt;br&gt;
@Modulithic(module = "notification")&lt;br&gt;
class NotificationEventListener {&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Autowired
private NotificationService notificationService;

@EventListener
public void handleAppointmentBooked(AppointmentBookedEvent event) {
    notificationService.sendAppointmentConfirmation(
        event.getPatientId(),
        event.getAppointmentId()
    );
}

@EventListener
public void handleBillGenerated(BillGeneratedEvent event) {
    notificationService.sendInvoiceNotification(
        event.getPatientId(),
        event.getInvoiceNumber()
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
🧩 Spring Modulith Architecture Diagram&lt;br&gt;
text&lt;br&gt;
                    ┌─────────────────────────────────────────┐&lt;br&gt;
                    │         MODULAR MONOLITH                │&lt;br&gt;
                    │         (Single Application)              │&lt;br&gt;
                    │                                           │&lt;br&gt;
                    │  ┌─────────────────────────────────────┐ │&lt;br&gt;
                    │  │         API GATEWAY LAYER           │ │&lt;br&gt;
                    │  │  (All REST Controllers)             │ │&lt;br&gt;
                    │  └─────────────────────────────────────┘ │&lt;br&gt;
                    │                      │                    │&lt;br&gt;
                    │  ┌──────────────────▼──────────────────┐ │&lt;br&gt;
                    │  │         MODULE BOUNDARIES            │ │&lt;br&gt;
                    │  │  ┌───────────────┐ ┌──────────────┐ │ │&lt;br&gt;
                    │  │  │   IDENTITY    │ │    DOCTOR    │ │ │&lt;br&gt;
                    │  │  │   MODULE      │ │    MODULE    │ │ │&lt;br&gt;
                    │  │  │  ┌─────────┐  │ │  ┌─────────┐ │ │ │&lt;br&gt;
                    │  │  │  │ PUBLIC  │  │ │  │ PUBLIC  │ │ │ │&lt;br&gt;
                    │  │  │  │   API   │  │ │  │   API   │ │ │ │&lt;br&gt;
                    │  │  │  └────┬────┘  │ │  └────┬────┘ │ │ │&lt;br&gt;
                    │  │  │  ┌────▼────┐  │ │  ┌────▼────┐ │ │ │&lt;br&gt;
                    │  │  │  │INTERNAL │  │ │  │INTERNAL │ │ │ │&lt;br&gt;
                    │  │  │  │  LOGIC  │  │ │  │  LOGIC  │ │ │ │&lt;br&gt;
                    │  │  │  └─────────┘  │ │  └─────────┘ │ │ │&lt;br&gt;
                    │  │  └────────────────┘ └──────────────┘ │ │&lt;br&gt;
                    │  │                                       │ │&lt;br&gt;
                    │  │  ┌────────────────┐ ┌──────────────┐ │ │&lt;br&gt;
                    │  │  │  APPOINTMENT   │ │   BILLING    │ │ │&lt;br&gt;
                    │  │  │    MODULE      │ │   MODULE     │ │ │&lt;br&gt;
                    │  │  │  ┌─────────┐   │ │  ┌─────────┐ │ │ │&lt;br&gt;
                    │  │  │  │ PUBLIC  │   │ │  │ PUBLIC  │ │ │ │&lt;br&gt;
                    │  │  │  │   API   │   │ │  │   API   │ │ │ │&lt;br&gt;
                    │  │  │  └────┬────┘   │ │  └────┬────┘ │ │ │&lt;br&gt;
                    │  │  │  ┌────▼────┐   │ │  ┌────▼────┐ │ │ │&lt;br&gt;
                    │  │  │  │INTERNAL │   │ │  │INTERNAL │ │ │ │&lt;br&gt;
                    │  │  │  │  LOGIC  │   │ │  │  LOGIC  │ │ │ │&lt;br&gt;
                    │  │  │  └─────────┘   │ │  └─────────┘ │ │ │&lt;br&gt;
                    │  │  └────────────────┘ └──────────────┘ │ │&lt;br&gt;
                    │  │                                       │ │&lt;br&gt;
                    │  │         ┌────────────────────┐       │ │&lt;br&gt;
                    │  │         │   NOTIFICATION     │       │ │&lt;br&gt;
                    │  │         │     MODULE         │       │ │&lt;br&gt;
                    │  │         │  ┌───────────────┐ │       │ │&lt;br&gt;
                    │  │         │  │    PUBLIC     │ │       │ │&lt;br&gt;
                    │  │         │  │     API       │ │       │ │&lt;br&gt;
                    │  │         │  └───────┬───────┘ │       │ │&lt;br&gt;
                    │  │         │  ┌───────▼───────┐ │       │ │&lt;br&gt;
                    │  │         │  │   INTERNAL    │ │       │ │&lt;br&gt;
                    │  │         │  │    LOGIC      │ │       │ │&lt;br&gt;
                    │  │         │  └───────────────┘ │       │ │&lt;br&gt;
                    │  │         └────────────────────┘       │ │&lt;br&gt;
                    │  └──────────────────▲───────────────────┘ │&lt;br&gt;
                    │                     │                     │&lt;br&gt;
                    │              ┌──────┴──────┐              │&lt;br&gt;
                    │              │ EVENT BUS   │              │&lt;br&gt;
                    │              │ (In-Memory) │              │&lt;br&gt;
                    │              └─────────────┘              │&lt;br&gt;
                    └─────────────────────┬───────────────────────┘&lt;br&gt;
                                          │&lt;br&gt;
                                ┌─────────▼─────────┐&lt;br&gt;
                                │   PostgreSQL DB   │&lt;br&gt;
                                │   (Single Schema)  │&lt;br&gt;
                                └───────────────────┘&lt;br&gt;
🛠️ Spring Modulith Configuration&lt;br&gt;
Add Modulith Dependency:&lt;/p&gt;

&lt;p&gt;xml&lt;br&gt;
&lt;br&gt;
    org.springframework.modulith&lt;br&gt;
    spring-modulith-starter-core&lt;br&gt;
    1.1.0&lt;br&gt;
&lt;br&gt;
Module Validation:&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
@SpringBootApplication&lt;br&gt;
public class OpdApplication {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        SpringApplication.run(OpdApplication.class, args);&lt;br&gt;
    }&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Verify module boundaries at startup
@Bean
ApplicationModuleInitializer moduleInitializer() {
    return () -&amp;gt; {
        var modules = ApplicationModules.of(OpdApplication.class);
        modules.verify();
        System.out.println("✅ Module boundaries verified!");
    };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
Module Documentation:&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
@org.springframework.modulith.ApplicationModule(&lt;br&gt;
    allowedDependencies = {"identity", "doctor"}&lt;br&gt;
)&lt;br&gt;
package com.hospital.opd.appointment;&lt;/p&gt;

&lt;p&gt;// This module can only depend on identity and doctor modules&lt;br&gt;
✅ Pros of Modular Monolith&lt;br&gt;
Clean Architecture&lt;/p&gt;

&lt;p&gt;Clear separation of concerns&lt;/p&gt;

&lt;p&gt;Enforced module boundaries&lt;/p&gt;

&lt;p&gt;No accidental dependencies&lt;/p&gt;

&lt;p&gt;Better Code Organization&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Each module owns its domain&lt;br&gt;
// Internal implementation can change without affecting others&lt;br&gt;
Easier Testing&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
@ModuleTest&lt;br&gt;
class AppointmentModuleTest {&lt;br&gt;
    // Test module in isolation&lt;br&gt;
    // Mock external module interactions&lt;br&gt;
}&lt;br&gt;
Future-Proof&lt;/p&gt;

&lt;p&gt;Easy to extract modules into microservices later&lt;/p&gt;

&lt;p&gt;Already has clear boundaries&lt;/p&gt;

&lt;p&gt;No Network Overhead&lt;/p&gt;

&lt;p&gt;Still fast in-JVM communication&lt;/p&gt;

&lt;p&gt;Events are lightweight&lt;/p&gt;

&lt;p&gt;❌ Cons of Modular Monolith&lt;br&gt;
Single Deployment Unit&lt;/p&gt;

&lt;p&gt;Still deploy everything together&lt;/p&gt;

&lt;p&gt;Can't scale modules independently&lt;/p&gt;

&lt;p&gt;Single Database&lt;/p&gt;

&lt;p&gt;All modules share one database&lt;/p&gt;

&lt;p&gt;Database becomes bottleneck&lt;/p&gt;

&lt;p&gt;Learning Curve&lt;/p&gt;

&lt;p&gt;Developers must understand module boundaries&lt;/p&gt;

&lt;p&gt;Need discipline to maintain separation&lt;/p&gt;

&lt;p&gt;🎯 When to Use Modular Monolith&lt;br&gt;
✅ Perfect for:&lt;/p&gt;

&lt;p&gt;Growing products with increasing complexity&lt;/p&gt;

&lt;p&gt;Medium-sized teams (5-15 developers)&lt;/p&gt;

&lt;p&gt;Systems preparing for microservices migration&lt;/p&gt;

&lt;p&gt;Projects needing clear architecture&lt;/p&gt;

&lt;p&gt;Most real-world business applications&lt;/p&gt;

&lt;p&gt;❌ Avoid when:&lt;/p&gt;

&lt;p&gt;You need independent scaling&lt;/p&gt;

&lt;p&gt;Each module requires different databases&lt;/p&gt;

&lt;p&gt;Teams are fully independent geographically&lt;/p&gt;

&lt;p&gt;👉 This is the sweet spot for most applications!&lt;/p&gt;

&lt;p&gt;3️⃣ MULTI-MODULE ARCHITECTURE&lt;br&gt;
Build-Time Modularization&lt;br&gt;
🔍 What is Multi-Module Architecture?&lt;br&gt;
Multi-module architecture uses Maven or Gradle to split code into separate modules at build time. Each module is a separate Maven/Gradle subproject, but they all combine into ONE final application.&lt;/p&gt;

&lt;p&gt;🏢 Real-Life Analogy&lt;br&gt;
Think of a hospital built from prefabricated sections:&lt;/p&gt;

&lt;p&gt;Each department (Identity, Doctor, Appointment) is built separately&lt;/p&gt;

&lt;p&gt;They're designed to fit together perfectly&lt;/p&gt;

&lt;p&gt;Once assembled, they form one complete hospital&lt;/p&gt;

&lt;p&gt;You can't move a department after construction&lt;/p&gt;

&lt;p&gt;📦 Detailed Multi-Module Project Structure&lt;br&gt;
text&lt;br&gt;
opd-multi-module/&lt;br&gt;
├── pom.xml (parent pom)&lt;br&gt;
├── identity-module/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   └── src/&lt;br&gt;
│       └── main/&lt;br&gt;
│           └── java/&lt;br&gt;
│               └── com/&lt;br&gt;
│                   └── hospital/&lt;br&gt;
│                       └── identity/&lt;br&gt;
│                           ├── IdentityApplication.java&lt;br&gt;
│                           ├── controller/&lt;br&gt;
│                           ├── service/&lt;br&gt;
│                           ├── repository/&lt;br&gt;
│                           ├── model/&lt;br&gt;
│                           └── config/&lt;br&gt;
├── doctor-module/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   └── src/&lt;br&gt;
│       └── main/&lt;br&gt;
│           └── java/&lt;br&gt;
│               └── com/&lt;br&gt;
│                   └── hospital/&lt;br&gt;
│                       └── doctor/&lt;br&gt;
│                           ├── DoctorApplication.java&lt;br&gt;
│                           ├── controller/&lt;br&gt;
│                           ├── service/&lt;br&gt;
│                           ├── repository/&lt;br&gt;
│                           ├── model/&lt;br&gt;
│                           └── config/&lt;br&gt;
├── appointment-module/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   └── src/&lt;br&gt;
│       └── main/&lt;br&gt;
│           └── java/&lt;br&gt;
│               └── com/&lt;br&gt;
│                   └── hospital/&lt;br&gt;
│                       └── appointment/&lt;br&gt;
│                           ├── AppointmentApplication.java&lt;br&gt;
│                           ├── controller/&lt;br&gt;
│                           ├── service/&lt;br&gt;
│                           ├── repository/&lt;br&gt;
│                           ├── model/&lt;br&gt;
│                           └── config/&lt;br&gt;
├── billing-module/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   └── src/&lt;br&gt;
│       └── main/&lt;br&gt;
│           └── java/&lt;br&gt;
│               └── com/&lt;br&gt;
│                   └── hospital/&lt;br&gt;
│                       └── billing/&lt;br&gt;
│                           ├── BillingApplication.java&lt;br&gt;
│                           ├── controller/&lt;br&gt;
│                           ├── service/&lt;br&gt;
│                           ├── repository/&lt;br&gt;
│                           ├── model/&lt;br&gt;
│                           └── config/&lt;br&gt;
├── notification-module/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   └── src/&lt;br&gt;
│       └── main/&lt;br&gt;
│           └── java/&lt;br&gt;
│               └── com/&lt;br&gt;
│                   └── hospital/&lt;br&gt;
│                       └── notification/&lt;br&gt;
│                           ├── NotificationApplication.java&lt;br&gt;
│                           ├── controller/&lt;br&gt;
│                           ├── service/&lt;br&gt;
│                           ├── repository/&lt;br&gt;
│                           ├── model/&lt;br&gt;
│                           └── config/&lt;br&gt;
└── application/&lt;br&gt;
    ├── pom.xml&lt;br&gt;
    └── src/&lt;br&gt;
        └── main/&lt;br&gt;
            └── java/&lt;br&gt;
                └── com/&lt;br&gt;
                    └── hospital/&lt;br&gt;
                        └── app/&lt;br&gt;
                            ├── HospitalApplication.java&lt;br&gt;
                            └── config/&lt;br&gt;
                                └── ModuleConfiguration.java&lt;br&gt;
📄 Maven Configuration Files&lt;br&gt;
Parent pom.xml:&lt;/p&gt;

&lt;p&gt;xml&lt;br&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br&gt;
&lt;br&gt;
    4.0.0&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;opd-multi-module&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;1.0.0&amp;lt;/version&amp;gt;
&amp;lt;packaging&amp;gt;pom&amp;lt;/packaging&amp;gt;

&amp;lt;modules&amp;gt;
    &amp;lt;module&amp;gt;identity-module&amp;lt;/module&amp;gt;
    &amp;lt;module&amp;gt;doctor-module&amp;lt;/module&amp;gt;
    &amp;lt;module&amp;gt;appointment-module&amp;lt;/module&amp;gt;
    &amp;lt;module&amp;gt;billing-module&amp;lt;/module&amp;gt;
    &amp;lt;module&amp;gt;notification-module&amp;lt;/module&amp;gt;
    &amp;lt;module&amp;gt;application&amp;lt;/module&amp;gt;
&amp;lt;/modules&amp;gt;

&amp;lt;parent&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-parent&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;3.1.5&amp;lt;/version&amp;gt;
&amp;lt;/parent&amp;gt;

&amp;lt;properties&amp;gt;
    &amp;lt;java.version&amp;gt;17&amp;lt;/java.version&amp;gt;
&amp;lt;/properties&amp;gt;

&amp;lt;dependencyManagement&amp;gt;
    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;identity-module&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;${project.version}&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;doctor-module&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;${project.version}&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;!-- Other module dependencies --&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&amp;lt;/dependencyManagement&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;
Module pom.xml (appointment-module):&lt;/p&gt;

&lt;p&gt;xml&lt;br&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br&gt;
&lt;br&gt;
    4.0.0&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;parent&amp;gt;
    &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;opd-multi-module&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0&amp;lt;/version&amp;gt;
&amp;lt;/parent&amp;gt;

&amp;lt;artifactId&amp;gt;appointment-module&amp;lt;/artifactId&amp;gt;
&amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;

&amp;lt;dependencies&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;spring-boot-starter-data-jpa&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;

    &amp;lt;!-- Dependencies on other modules --&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;doctor-module&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;identity-module&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;
Application Module pom.xml:&lt;/p&gt;

&lt;p&gt;xml&lt;br&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br&gt;
&lt;br&gt;
    4.0.0&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;parent&amp;gt;
    &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;opd-multi-module&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0&amp;lt;/version&amp;gt;
&amp;lt;/parent&amp;gt;

&amp;lt;artifactId&amp;gt;application&amp;lt;/artifactId&amp;gt;
&amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;

&amp;lt;dependencies&amp;gt;
    &amp;lt;!-- Include all modules --&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;identity-module&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;doctor-module&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;appointment-module&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;billing-module&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;com.hospital&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;notification-module&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;

&amp;lt;build&amp;gt;
    &amp;lt;plugins&amp;gt;
        &amp;lt;plugin&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;configuration&amp;gt;
                &amp;lt;mainClass&amp;gt;com.hospital.app.HospitalApplication&amp;lt;/mainClass&amp;gt;
            &amp;lt;/configuration&amp;gt;
        &amp;lt;/plugin&amp;gt;
    &amp;lt;/plugins&amp;gt;
&amp;lt;/build&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;
🔄 How Modules Communicate in Multi-Module&lt;br&gt;
Communication is through compile-time dependencies and direct method calls.&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Appointment Module Service&lt;br&gt;
package com.hospital.appointment.service;&lt;/p&gt;

&lt;p&gt;@Service&lt;br&gt;
public class AppointmentService {&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Direct dependency on other modules
private final DoctorService doctorService;
private final IdentityService identityService;
private final BillingService billingService;

public AppointmentService(
        DoctorService doctorService,
        IdentityService identityService,
        BillingService billingService) {
    this.doctorService = doctorService;
    this.identityService = identityService;
    this.billingService = billingService;
}

@Transactional
public AppointmentDTO bookAppointment(AppointmentRequest request) {
    // Direct calls to other modules' services
    DoctorDTO doctor = doctorService.findAvailableDoctor(
        request.getDoctorId(), 
        request.getDateTime()
    );

    UserDTO patient = identityService.findById(request.getPatientId());

    Appointment appointment = new Appointment();
    appointment.setDoctorId(doctor.getId());
    appointment.setPatientId(patient.getId());
    appointment.setDateTime(request.getDateTime());
    appointment.setStatus("BOOKED");

    appointment = appointmentRepository.save(appointment);

    // Call billing module directly
    InvoiceDTO invoice = billingService.createInvoice(
        appointment.getId(),
        patient.getId(),
        doctor.getConsultationFee()
    );

    return mapToDTO(appointment);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
🧩 Multi-Module Architecture Diagram&lt;br&gt;
text&lt;br&gt;
                    ┌──────────────────────────────────────────┐&lt;br&gt;
                    │          MULTI-MODULE PROJECT            │&lt;br&gt;
                    │         (Maven/Gradle Parent)            │&lt;br&gt;
                    │                                           │&lt;br&gt;
                    │  ┌─────────────────────────────────────┐ │&lt;br&gt;
                    │  │         COMPILE TIME                │ │&lt;br&gt;
                    │  │         DEPENDENCY TREE              │ │&lt;br&gt;
                    │  │                                       │ │&lt;br&gt;
                    │  │    identity-module.jar               │ │&lt;br&gt;
                    │  │           ▲                          │ │&lt;br&gt;
                    │  │           │ depends                  │ │&lt;br&gt;
                    │  │    doctor-module.jar                 │ │&lt;br&gt;
                    │  │           ▲                          │ │&lt;br&gt;
                    │  │           │ depends                  │ │&lt;br&gt;
                    │  │    appointment-module.jar  ◄──┐     │ │&lt;br&gt;
                    │  │           ▲                     │     │ │&lt;br&gt;
                    │  │           │ depends              │     │ │&lt;br&gt;
                    │  │    billing-module.jar  ─────────┘     │ │&lt;br&gt;
                    │  │           ▲                          │ │&lt;br&gt;
                    │  │           │ depends                  │ │&lt;br&gt;
                    │  │    notification-module.jar           │ │&lt;br&gt;
                    │  │           ▲                          │ │&lt;br&gt;
                    │  │           │ depends                  │ │&lt;br&gt;
                    │  │    application.jar                   │ │&lt;br&gt;
                    │  │    (Final Assembly)                  │ │&lt;br&gt;
                    │  └─────────────────────────────────────┘ │&lt;br&gt;
                    │                      │                    │&lt;br&gt;
                    │  ┌──────────────────▼──────────────────┐ │&lt;br&gt;
                    │  │         RUNTIME (Single JVM)        │ │&lt;br&gt;
                    │  │                                      │ │&lt;br&gt;
                    │  │    ┌───────────────────────────┐   │ │&lt;br&gt;
                    │  │    │   ONE SPRING BOOT APP     │   │ │&lt;br&gt;
                    │  │    │   with all modules        │   │ │&lt;br&gt;
                    │  │    │   loaded together         │   │ │&lt;br&gt;
                    │  │    └───────────────────────────┘   │ │&lt;br&gt;
                    │  │              │                      │ │&lt;br&gt;
                    │  │     ┌────────┴────────┐            │ │&lt;br&gt;
                    │  │     │  PostgreSQL DB  │            │ │&lt;br&gt;
                    │  │     │  (Single Schema) │            │ │&lt;br&gt;
                    │  │     └─────────────────┘            │ │&lt;br&gt;
                    │  └─────────────────────────────────────┘ │&lt;br&gt;
                    └──────────────────────────────────────────┘&lt;br&gt;
💡 Key Differences from Modular Monolith&lt;br&gt;
java&lt;br&gt;
// In Multi-Module: Compile-time dependencies&lt;br&gt;
// appointment-module/pom.xml explicitly declares:&lt;br&gt;
&lt;br&gt;
    com.hospital&lt;br&gt;
    doctor-module&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;// In Modular Monolith: Runtime module boundaries&lt;br&gt;
// No explicit dependency declaration needed in pom.xml&lt;br&gt;
// Boundaries are enforced by package structure and Spring Modulith&lt;br&gt;
✅ Pros of Multi-Module&lt;br&gt;
Clear Build Dependencies&lt;/p&gt;

&lt;p&gt;xml&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
    com.hospital&lt;br&gt;
    billing-module&lt;br&gt;
&lt;br&gt;
Parallel Development&lt;/p&gt;

&lt;p&gt;Teams can work on different modules&lt;/p&gt;

&lt;p&gt;Clear ownership&lt;/p&gt;

&lt;p&gt;Independent versioning&lt;/p&gt;

&lt;p&gt;Reusable Modules&lt;/p&gt;

&lt;p&gt;xml&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
    com.hospital&lt;br&gt;
    notification-module&lt;br&gt;
    1.0.0&lt;br&gt;
&lt;br&gt;
Faster Builds&lt;/p&gt;

&lt;p&gt;Maven/Gradle incremental builds&lt;/p&gt;

&lt;p&gt;Only rebuild changed modules&lt;/p&gt;

&lt;p&gt;Better IDE Support&lt;/p&gt;

&lt;p&gt;IntelliJ/Eclipse understand module structure&lt;/p&gt;

&lt;p&gt;Easy navigation between modules&lt;/p&gt;

&lt;p&gt;❌ Cons of Multi-Module&lt;br&gt;
Tight Coupling at Runtime&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Even though modules are separate at build time,&lt;br&gt;
// at runtime they're all in one JVM with no boundaries&lt;br&gt;
No Runtime Isolation&lt;/p&gt;

&lt;p&gt;One module's memory leak affects all&lt;/p&gt;

&lt;p&gt;Can't restart just one module&lt;/p&gt;

&lt;p&gt;Complex Refactoring&lt;/p&gt;

&lt;p&gt;Moving code between modules requires dependency changes&lt;/p&gt;

&lt;p&gt;Circular dependencies possible&lt;/p&gt;

&lt;p&gt;🎯 When to Use Multi-Module&lt;br&gt;
✅ Perfect for:&lt;/p&gt;

&lt;p&gt;Large codebases needing organization&lt;/p&gt;

&lt;p&gt;Multiple teams sharing code&lt;/p&gt;

&lt;p&gt;Projects with reusable components&lt;/p&gt;

&lt;p&gt;Enterprise internal systems&lt;/p&gt;

&lt;p&gt;Libraries and frameworks&lt;/p&gt;

&lt;p&gt;❌ Avoid when:&lt;/p&gt;

&lt;p&gt;You need runtime isolation&lt;/p&gt;

&lt;p&gt;Modules need independent scaling&lt;/p&gt;

&lt;p&gt;You want strict runtime boundaries&lt;/p&gt;

&lt;p&gt;4️⃣ MICROSERVICES ARCHITECTURE&lt;br&gt;
Fully Distributed System&lt;br&gt;
🔍 What are Microservices?&lt;br&gt;
Microservices architecture splits the application into completely independent services. Each service:&lt;/p&gt;

&lt;p&gt;Is its own Spring Boot application&lt;/p&gt;

&lt;p&gt;Has its own database&lt;/p&gt;

&lt;p&gt;Can be deployed independently&lt;/p&gt;

&lt;p&gt;Communicates over network&lt;/p&gt;

&lt;p&gt;🏢 Real-Life Analogy&lt;br&gt;
Think of a hospital campus with separate buildings:&lt;/p&gt;

&lt;p&gt;Identity building (separate structure)&lt;/p&gt;

&lt;p&gt;Doctor's office building&lt;/p&gt;

&lt;p&gt;Appointment center&lt;/p&gt;

&lt;p&gt;Billing department building&lt;/p&gt;

&lt;p&gt;Notification center&lt;/p&gt;

&lt;p&gt;Each building has:&lt;/p&gt;

&lt;p&gt;Its own staff&lt;/p&gt;

&lt;p&gt;Its own resources&lt;/p&gt;

&lt;p&gt;Its own phone system&lt;/p&gt;

&lt;p&gt;Communication happens via phones/couriers (network)&lt;/p&gt;

&lt;p&gt;📦 Microservices Project Structure&lt;br&gt;
text&lt;br&gt;
hospital-system/&lt;br&gt;
├── identity-service/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   ├── src/&lt;br&gt;
│   │   └── main/&lt;br&gt;
│   │       ├── java/com/hospital/identity/&lt;br&gt;
│   │       │   ├── IdentityServiceApplication.java&lt;br&gt;
│   │       │   ├── controller/&lt;br&gt;
│   │       │   ├── service/&lt;br&gt;
│   │       │   ├── repository/&lt;br&gt;
│   │       │   ├── model/&lt;br&gt;
│   │       │   └── config/&lt;br&gt;
│   │       └── resources/&lt;br&gt;
│   │           ├── application.properties&lt;br&gt;
│   │           └── db/migration/&lt;br&gt;
│   └── Dockerfile&lt;br&gt;
│&lt;br&gt;
├── doctor-service/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   ├── src/&lt;br&gt;
│   │   └── main/&lt;br&gt;
│   │       ├── java/com/hospital/doctor/&lt;br&gt;
│   │       │   ├── DoctorServiceApplication.java&lt;br&gt;
│   │       │   ├── controller/&lt;br&gt;
│   │       │   ├── service/&lt;br&gt;
│   │       │   ├── repository/&lt;br&gt;
│   │       │   ├── model/&lt;br&gt;
│   │       │   └── client/&lt;br&gt;
│   │       │       ├── IdentityServiceClient.java&lt;br&gt;
│   │       │       └── AppointmentServiceClient.java&lt;br&gt;
│   │       └── resources/&lt;br&gt;
│   │           ├── application.properties&lt;br&gt;
│   │           └── db/migration/&lt;br&gt;
│   └── Dockerfile&lt;br&gt;
│&lt;br&gt;
├── appointment-service/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   ├── src/&lt;br&gt;
│   │   └── main/&lt;br&gt;
│   │       ├── java/com/hospital/appointment/&lt;br&gt;
│   │       │   ├── AppointmentServiceApplication.java&lt;br&gt;
│   │       │   ├── controller/&lt;br&gt;
│   │       │   ├── service/&lt;br&gt;
│   │       │   ├── repository/&lt;br&gt;
│   │       │   ├── model/&lt;br&gt;
│   │       │   └── client/&lt;br&gt;
│   │       │       ├── DoctorServiceClient.java&lt;br&gt;
│   │       │       └── IdentityServiceClient.java&lt;br&gt;
│   │       └── resources/&lt;br&gt;
│   │           ├── application.properties&lt;br&gt;
│   │           └── db/migration/&lt;br&gt;
│   └── Dockerfile&lt;br&gt;
│&lt;br&gt;
├── billing-service/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   ├── src/&lt;br&gt;
│   │   └── main/&lt;br&gt;
│   │       ├── java/com/hospital/billing/&lt;br&gt;
│   │       │   ├── BillingServiceApplication.java&lt;br&gt;
│   │       │   ├── controller/&lt;br&gt;
│   │       │   ├── service/&lt;br&gt;
│   │       │   ├── repository/&lt;br&gt;
│   │       │   ├── model/&lt;br&gt;
│   │       │   └── consumer/&lt;br&gt;
│   │       │       └── AppointmentEventConsumer.java&lt;br&gt;
│   │       └── resources/&lt;br&gt;
│   │           ├── application.properties&lt;br&gt;
│   │           └── db/migration/&lt;br&gt;
│   └── Dockerfile&lt;br&gt;
│&lt;br&gt;
├── notification-service/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   ├── src/&lt;br&gt;
│   │   └── main/&lt;br&gt;
│   │       ├── java/com/hospital/notification/&lt;br&gt;
│   │       │   ├── NotificationServiceApplication.java&lt;br&gt;
│   │       │   ├── controller/&lt;br&gt;
│   │       │   ├── service/&lt;br&gt;
│   │       │   ├── repository/&lt;br&gt;
│   │       │   ├── model/&lt;br&gt;
│   │       │   └── consumer/&lt;br&gt;
│   │       │       ├── AppointmentEventConsumer.java&lt;br&gt;
│   │       │       └── BillingEventConsumer.java&lt;br&gt;
│   │       └── resources/&lt;br&gt;
│   │           ├── application.properties&lt;br&gt;
│   │           └── db/migration/&lt;br&gt;
│   └── Dockerfile&lt;br&gt;
│&lt;br&gt;
├── api-gateway/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   ├── src/&lt;br&gt;
│   │   └── main/&lt;br&gt;
│   │       ├── java/com/hospital/gateway/&lt;br&gt;
│   │       │   ├── GatewayApplication.java&lt;br&gt;
│   │       │   └── config/&lt;br&gt;
│   │       │       ├── RouteConfig.java&lt;br&gt;
│   │       │       └── SecurityConfig.java&lt;br&gt;
│   │       └── resources/&lt;br&gt;
│   │           └── application.properties&lt;br&gt;
│   └── Dockerfile&lt;br&gt;
│&lt;br&gt;
├── service-registry/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   ├── src/&lt;br&gt;
│   │   └── main/&lt;br&gt;
│   │       ├── java/com/hospital/registry/&lt;br&gt;
│   │       │   ├── RegistryApplication.java&lt;br&gt;
│   │       │   └── config/&lt;br&gt;
│   │       │       └── SecurityConfig.java&lt;br&gt;
│   │       └── resources/&lt;br&gt;
│   │           └── application.properties&lt;br&gt;
│   └── Dockerfile&lt;br&gt;
│&lt;br&gt;
├── config-server/&lt;br&gt;
│   ├── pom.xml&lt;br&gt;
│   ├── src/&lt;br&gt;
│   │   └── main/&lt;br&gt;
│   │       ├── java/com/hospital/config/&lt;br&gt;
│   │       │   └── ConfigServerApplication.java&lt;br&gt;
│   │       └── resources/&lt;br&gt;
│   │           └── application.properties&lt;br&gt;
│   └── Dockerfile&lt;br&gt;
│&lt;br&gt;
├── docker-compose.yml&lt;br&gt;
├── kubernetes/&lt;br&gt;
│   ├── deployments/&lt;br&gt;
│   └── services/&lt;br&gt;
└── README.md&lt;br&gt;
🔧 Infrastructure Components&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Service Registry (Eureka)
java
// service-registry/src/main/java/com/hospital/registry/RegistryApplication.java
@SpringBootApplication
@EnableEurekaServer
public class RegistryApplication {
public static void main(String[] args) {
    SpringApplication.run(RegistryApplication.class, args);
}
}
properties
# service-registry/src/main/resources/application.properties
spring.application.name=service-registry
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;API Gateway (Spring Cloud Gateway)&lt;br&gt;
java&lt;br&gt;
// api-gateway/src/main/java/com/hospital/gateway/config/RouteConfig.java&lt;br&gt;
@Configuration&lt;br&gt;
public class RouteConfig {&lt;/p&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/bean"&gt;@bean&lt;/a&gt;&lt;br&gt;
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {&lt;br&gt;
    return builder.routes()&lt;br&gt;
        .route("identity-service", r -&amp;gt; r&lt;br&gt;
            .path("/api/auth/&lt;strong&gt;", "/api/users/&lt;/strong&gt;")&lt;br&gt;
            .uri("lb://IDENTITY-SERVICE"))&lt;br&gt;
        .route("doctor-service", r -&amp;gt; r&lt;br&gt;
            .path("/api/doctors/&lt;strong&gt;")&lt;br&gt;
            .uri("lb://DOCTOR-SERVICE"))&lt;br&gt;
        .route("appointment-service", r -&amp;gt; r&lt;br&gt;
            .path("/api/appointments/&lt;/strong&gt;")&lt;br&gt;
            .uri("lb://APPOINTMENT-SERVICE"))&lt;br&gt;
        .route("billing-service", r -&amp;gt; r&lt;br&gt;
            .path("/api/bills/&lt;strong&gt;", "/api/invoices/&lt;/strong&gt;")&lt;br&gt;
            .uri("lb://BILLING-SERVICE"))&lt;br&gt;
        .build();&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/bean"&gt;@bean&lt;/a&gt;&lt;br&gt;
public GlobalFilter customGlobalFilter() {&lt;br&gt;
    return (exchange, chain) -&amp;gt; {&lt;br&gt;
        // Add correlation ID for tracing&lt;br&gt;
        String correlationId = UUID.randomUUID().toString();&lt;br&gt;
        exchange = exchange.mutate()&lt;br&gt;
            .request(r -&amp;gt; r.header("X-Correlation-ID", correlationId))&lt;br&gt;
            .build();&lt;br&gt;
        return chain.filter(exchange);&lt;br&gt;
    };&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
🔄 Service Communication Patterns&lt;br&gt;
Pattern 1: Synchronous REST Communication&lt;br&gt;
java&lt;br&gt;
// doctor-service/src/main/java/com/hospital/doctor/client/IdentityServiceClient.java&lt;br&gt;
@FeignClient(name = "identity-service", url = "${identity.service.url}")&lt;br&gt;
public interface IdentityServiceClient {&lt;/p&gt;

&lt;p&gt;@GetMapping("/api/users/{userId}")&lt;br&gt;
UserDTO getUserById(@PathVariable("userId") Long userId);&lt;/p&gt;

&lt;p&gt;@GetMapping("/api/users/validate")&lt;br&gt;
Boolean validateUser(@RequestParam("email") String email, &lt;br&gt;
                    @RequestParam("password") String password);&lt;br&gt;
}&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;// appointment-service/src/main/java/com/hospital/appointment/client/DoctorServiceClient.java&lt;br&gt;
@FeignClient(name = "doctor-service")&lt;br&gt;
public interface DoctorServiceClient {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@GetMapping("/api/doctors/{doctorId}/availability")
AvailabilityDTO checkAvailability(
    @PathVariable("doctorId") Long doctorId,
    @RequestParam("dateTime") String dateTime
);

@PostMapping("/api/doctors/{doctorId}/book-slot")
void bookDoctorSlot(
    @PathVariable("doctorId") Long doctorId,
    @RequestBody SlotBookingRequest request
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// appointment-service/src/main/java/com/hospital/appointment/service/AppointmentService.java&lt;br&gt;
@Service&lt;br&gt;
public class AppointmentService {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private final DoctorServiceClient doctorClient;
private final IdentityServiceClient identityClient;

public AppointmentDTO bookAppointment(AppointmentRequest request) {
    // 1. Validate patient with identity service (REST call)
    UserDTO patient = identityClient.getUserById(request.getPatientId());

    // 2. Check doctor availability (REST call)
    AvailabilityDTO availability = doctorClient.checkAvailability(
        request.getDoctorId(),
        request.getDateTime()
    );

    if (!availability.isAvailable()) {
        throw new AppointmentNotAvailableException();
    }

    // 3. Book doctor slot (REST call)
    doctorClient.bookDoctorSlot(
        request.getDoctorId(),
        new SlotBookingRequest(request.getDateTime(), request.getPatientId())
    );

    // 4. Create appointment locally
    Appointment appointment = createAppointment(request, patient);
    appointment = appointmentRepository.save(appointment);

    return mapToDTO(appointment);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Pattern 2: Asynchronous Event Communication with Kafka&lt;br&gt;
java&lt;br&gt;
// 1. Define Common Event Classes (shared library)&lt;br&gt;
// shared-events/src/main/java/com/hospital/events/AppointmentBookedEvent.java&lt;br&gt;
public class AppointmentBookedEvent {&lt;br&gt;
    private Long appointmentId;&lt;br&gt;
    private Long patientId;&lt;br&gt;
    private Long doctorId;&lt;br&gt;
    private LocalDateTime appointmentTime;&lt;br&gt;
    private BigDecimal consultationFee;&lt;br&gt;
    private String patientEmail;&lt;br&gt;
    private String patientPhone;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// constructors, getters, setters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// 2. Appointment Service - Event Publisher&lt;br&gt;
// appointment-service/src/main/java/com/hospital/appointment/service/AppointmentService.java&lt;br&gt;
@Service&lt;br&gt;
public class AppointmentService {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Autowired
private KafkaTemplate&amp;lt;String, AppointmentBookedEvent&amp;gt; kafkaTemplate;

@Transactional
public AppointmentDTO bookAppointment(AppointmentRequest request) {
    // Create appointment
    Appointment appointment = createAppointment(request);
    appointment = appointmentRepository.save(appointment);

    // Publish event to Kafka
    AppointmentBookedEvent event = new AppointmentBookedEvent(
        appointment.getId(),
        appointment.getPatientId(),
        appointment.getDoctorId(),
        appointment.getDateTime(),
        appointment.getConsultationFee(),
        appointment.getPatientEmail(),
        appointment.getPatientPhone()
    );

    kafkaTemplate.send("appointment-events", event);

    return mapToDTO(appointment);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// 3. Billing Service - Event Consumer&lt;br&gt;
// billing-service/src/main/java/com/hospital/billing/consumer/AppointmentEventConsumer.java&lt;br&gt;
@Service&lt;br&gt;
public class AppointmentEventConsumer {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Autowired
private BillingService billingService;

@KafkaListener(topics = "appointment-events", groupId = "billing-group")
public void handleAppointmentBooked(AppointmentBookedEvent event) {
    log.info("Received appointment booked event: {}", event.getAppointmentId());

    // Generate bill
    Invoice invoice = billingService.generateInvoice(
        event.getAppointmentId(),
        event.getPatientId(),
        event.getConsultationFee()
    );

    // Publish billing event for notification service
    BillGeneratedEvent billEvent = new BillGeneratedEvent(
        invoice.getId(),
        event.getPatientId(),
        invoice.getAmount(),
        event.getPatientEmail(),
        event.getPatientPhone()
    );

    kafkaTemplate.send("billing-events", billEvent);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// 4. Notification Service - Multiple Event Consumers&lt;br&gt;
// notification-service/src/main/java/com/hospital/notification/consumer/EventConsumer.java&lt;br&gt;
@Service&lt;br&gt;
public class EventConsumer {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Autowired
private NotificationService notificationService;

@KafkaListener(topics = "appointment-events", groupId = "notification-group")
public void handleAppointmentBooked(AppointmentBookedEvent event) {
    notificationService.sendAppointmentConfirmation(
        event.getPatientEmail(),
        event.getPatientPhone(),
        event.getAppointmentId(),
        event.getAppointmentTime()
    );
}

@KafkaListener(topics = "billing-events", groupId = "notification-group")
public void handleBillGenerated(BillGeneratedEvent event) {
    notificationService.sendInvoiceNotification(
        event.getPatientEmail(),
        event.getPatientPhone(),
        event.getInvoiceId(),
        event.getAmount()
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
🧩 Microservices Architecture Diagram&lt;br&gt;
text&lt;br&gt;
┌─────────────────────────────────────────────────────────────────────┐&lt;br&gt;
│                         CLIENT APPLICATIONS                          │&lt;br&gt;
│                  (Web, Mobile, Third-party APIs)                     │&lt;br&gt;
└────────────────────────────────────┬────────────────────────────────┘&lt;br&gt;
                                     │&lt;br&gt;
                                     ▼&lt;br&gt;
┌─────────────────────────────────────────────────────────────────────┐&lt;br&gt;
│                         API GATEWAY                                   │&lt;br&gt;
│                    (Spring Cloud Gateway)                            │&lt;br&gt;
│                                                                       │&lt;br&gt;
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐              │&lt;br&gt;
│  │   Routing    │  │   Rate       │  │   Security   │              │&lt;br&gt;
│  │              │  │   Limiting   │  │              │              │&lt;br&gt;
│  └──────────────┘  └──────────────┘  └──────────────┘              │&lt;br&gt;
└────────────┬─────────────────────────────┬──────────────────────────┘&lt;br&gt;
             │                             │&lt;br&gt;
             ▼                             ▼&lt;br&gt;
┌────────────────────────┐      ┌────────────────────────┐&lt;br&gt;
│   SERVICE REGISTRY     │      │   CONFIG SERVER        │&lt;br&gt;
│    (Eureka Server)     │◄────►│   (Spring Cloud Config)│&lt;br&gt;
│   service discovery    │      │   centralized config   │&lt;br&gt;
└────────────────────────┘      └────────────────────────┘&lt;br&gt;
        │&lt;br&gt;&lt;br&gt;
        │ Service Registration&lt;br&gt;&lt;br&gt;
        ▼&lt;br&gt;&lt;br&gt;
┌─────────────────────────────────────────────────────────────────────┐&lt;br&gt;
│                         MICROSERVICES                                │&lt;br&gt;
│                                                                       │&lt;br&gt;
│  ┌────────────────┐     ┌────────────────┐     ┌────────────────┐  │&lt;br&gt;
│  │   IDENTITY     │     │    DOCTOR      │     │  APPOINTMENT   │  │&lt;br&gt;
│  │   SERVICE      │     │    SERVICE     │     │   SERVICE      │  │&lt;br&gt;
│  │                │     │                │     │                │  │&lt;br&gt;
│  │ ┌──────────┐   │     │ ┌──────────┐   │     │ ┌──────────┐   │  │&lt;br&gt;
│  │ │PostgreSQL│   │     │ │PostgreSQL│   │     │ │PostgreSQL│   │  │&lt;br&gt;
│  │ │   DB 1   │   │     │ │   DB 2   │   │     │ │   DB 3   │   │  │&lt;br&gt;
│  │ └──────────┘   │     │ └──────────┘   │     │ └──────────┘   │  │&lt;br&gt;
│  └────────────────┘     └────────────────┘     └────────────────┘  │&lt;br&gt;
│                                                                       │&lt;br&gt;
│  ┌────────────────┐     ┌────────────────┐                          │&lt;br&gt;
│  │   BILLING      │     │  NOTIFICATION  │                          │&lt;br&gt;
│  │   SERVICE      │     │   SERVICE      │                          │&lt;br&gt;
│  │                │     │                │                          │&lt;br&gt;
│  │ ┌──────────┐   │     │ ┌──────────┐   │                          │&lt;br&gt;
│  │ │PostgreSQL│   │     │ │PostgreSQL│   │                          │&lt;br&gt;
│  │ │   DB 4   │   │     │ │   DB 5   │   │                          │&lt;br&gt;
│  │ └──────────┘   │     │ └──────────┘   │                          │&lt;br&gt;
│  └────────────────┘     └────────────────┘                          │&lt;br&gt;
└─────────────────────────────────────────────────────────────────────┘&lt;br&gt;
                              │&lt;br&gt;
                              ▼&lt;br&gt;
┌─────────────────────────────────────────────────────────────────────┐&lt;br&gt;
│                         MESSAGE BROKER                               │&lt;br&gt;
│                         (Apache Kafka)                               │&lt;br&gt;
│                                                                       │&lt;br&gt;
│  ┌─────────────────────────────────────────────────────────────┐    │&lt;br&gt;
│  │  Topics: appointment-events, billing-events, notification-events│&lt;br&gt;
│  └─────────────────────────────────────────────────────────────┘    │&lt;br&gt;
└─────────────────────────────────────────────────────────────────────┘&lt;br&gt;
                              │&lt;br&gt;
                              ▼&lt;br&gt;
┌─────────────────────────────────────────────────────────────────────┐&lt;br&gt;
│                         MONITORING STACK                             │&lt;br&gt;
│                                                                       │&lt;br&gt;
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐              │&lt;br&gt;
│  │  Prometheus  │  │   Grafana    │  │   Zipkin     │              │&lt;br&gt;
│  │   Metrics    │  │  Dashboard   │  │  Tracing     │              │&lt;br&gt;
│  └──────────────┘  └──────────────┘  └──────────────┘              │&lt;br&gt;
└─────────────────────────────────────────────────────────────────────┘&lt;br&gt;
📝 Service Configuration&lt;br&gt;
application.yml for Appointment Service:&lt;/p&gt;

&lt;p&gt;yaml&lt;br&gt;
spring:&lt;br&gt;
  application:&lt;br&gt;
    name: appointment-service&lt;/p&gt;

&lt;p&gt;datasource:&lt;br&gt;
    url: jdbc:postgresql://localhost:5432/appointment_db&lt;br&gt;
    username: app_user&lt;br&gt;
    password: ${DB_PASSWORD}&lt;/p&gt;

&lt;p&gt;jpa:&lt;br&gt;
    hibernate:&lt;br&gt;
      ddl-auto: validate&lt;br&gt;
    show-sql: false&lt;/p&gt;

&lt;p&gt;kafka:&lt;br&gt;
    bootstrap-servers: localhost:9092&lt;br&gt;
    producer:&lt;br&gt;
      key-serializer: org.apache.kafka.common.serialization.StringSerializer&lt;br&gt;
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer&lt;br&gt;
    consumer:&lt;br&gt;
      group-id: appointment-group&lt;br&gt;
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer&lt;br&gt;
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer&lt;br&gt;
      properties:&lt;br&gt;
        spring.json.trusted.packages: "*"&lt;/p&gt;

&lt;p&gt;eureka:&lt;br&gt;
  client:&lt;br&gt;
    service-url:&lt;br&gt;
      defaultZone: &lt;a href="http://localhost:8761/eureka/" rel="noopener noreferrer"&gt;http://localhost:8761/eureka/&lt;/a&gt;&lt;br&gt;
  instance:&lt;br&gt;
    hostname: localhost&lt;br&gt;
    prefer-ip-address: true&lt;/p&gt;

&lt;p&gt;server:&lt;br&gt;
  port: 8083&lt;/p&gt;

&lt;p&gt;management:&lt;br&gt;
  endpoints:&lt;br&gt;
    web:&lt;br&gt;
      exposure:&lt;br&gt;
        include: health,info,metrics,prometheus&lt;br&gt;
🐳 Docker Compose Configuration&lt;br&gt;
yaml&lt;/p&gt;

&lt;h1&gt;
  
  
  docker-compose.yml
&lt;/h1&gt;

&lt;p&gt;version: '3.8'&lt;/p&gt;

&lt;p&gt;services:&lt;br&gt;
  # Databases&lt;br&gt;
  postgres-identity:&lt;br&gt;
    image: postgres:15&lt;br&gt;
    environment:&lt;br&gt;
      POSTGRES_DB: identity_db&lt;br&gt;
      POSTGRES_USER: identity_user&lt;br&gt;
      POSTGRES_PASSWORD: ${IDENTITY_DB_PASSWORD}&lt;br&gt;
    volumes:&lt;br&gt;
      - identity-data:/var/lib/postgresql/data&lt;br&gt;
    ports:&lt;br&gt;
      - "5432:5432"&lt;/p&gt;

&lt;p&gt;postgres-doctor:&lt;br&gt;
    image: postgres:15&lt;br&gt;
    environment:&lt;br&gt;
      POSTGRES_DB: doctor_db&lt;br&gt;
      POSTGRES_USER: doctor_user&lt;br&gt;
      POSTGRES_PASSWORD: ${DOCTOR_DB_PASSWORD}&lt;br&gt;
    volumes:&lt;br&gt;
      - doctor-data:/var/lib/postgresql/data&lt;br&gt;
    ports:&lt;br&gt;
      - "5433:5432"&lt;/p&gt;

&lt;p&gt;postgres-appointment:&lt;br&gt;
    image: postgres:15&lt;br&gt;
    environment:&lt;br&gt;
      POSTGRES_DB: appointment_db&lt;br&gt;
      POSTGRES_USER: appointment_user&lt;br&gt;
      POSTGRES_PASSWORD: ${APPOINTMENT_DB_PASSWORD}&lt;br&gt;
    volumes:&lt;br&gt;
      - appointment-data:/var/lib/postgresql/data&lt;br&gt;
    ports:&lt;br&gt;
      - "5434:5432"&lt;/p&gt;

&lt;p&gt;# Message Broker&lt;br&gt;
  zookeeper:&lt;br&gt;
    image: confluentinc/cp-zookeeper:latest&lt;br&gt;
    environment:&lt;br&gt;
      ZOOKEEPER_CLIENT_PORT: 2181&lt;br&gt;
      ZOOKEEPER_TICK_TIME: 2000&lt;br&gt;
    ports:&lt;br&gt;
      - "2181:2181"&lt;/p&gt;

&lt;p&gt;kafka:&lt;br&gt;
    image: confluentinc/cp-kafka:latest&lt;br&gt;
    depends_on:&lt;br&gt;
      - zookeeper&lt;br&gt;
    ports:&lt;br&gt;
      - "9092:9092"&lt;br&gt;
    environment:&lt;br&gt;
      KAFKA_BROKER_ID: 1&lt;br&gt;
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181&lt;br&gt;
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092&lt;br&gt;
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1&lt;/p&gt;

&lt;p&gt;# Service Registry&lt;br&gt;
  service-registry:&lt;br&gt;
    build: ./service-registry&lt;br&gt;
    ports:&lt;br&gt;
      - "8761:8761"&lt;br&gt;
    environment:&lt;br&gt;
      - SPRING_PROFILES_ACTIVE=docker&lt;/p&gt;

&lt;p&gt;# Config Server&lt;br&gt;
  config-server:&lt;br&gt;
    build: ./config-server&lt;br&gt;
    ports:&lt;br&gt;
      - "8888:8888"&lt;br&gt;
    environment:&lt;br&gt;
      - SPRING_PROFILES_ACTIVE=docker&lt;/p&gt;

&lt;p&gt;# API Gateway&lt;br&gt;
  api-gateway:&lt;br&gt;
    build: ./api-gateway&lt;br&gt;
    ports:&lt;br&gt;
      - "8080:8080"&lt;br&gt;
    depends_on:&lt;br&gt;
      - service-registry&lt;br&gt;
      - config-server&lt;br&gt;
    environment:&lt;br&gt;
      - SPRING_PROFILES_ACTIVE=docker&lt;br&gt;
      - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=&lt;a href="http://service-registry:8761/eureka/" rel="noopener noreferrer"&gt;http://service-registry:8761/eureka/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;# Microservices&lt;br&gt;
  identity-service:&lt;br&gt;
    build: ./identity-service&lt;br&gt;
    depends_on:&lt;br&gt;
      - postgres-identity&lt;br&gt;
      - service-registry&lt;br&gt;
      - config-server&lt;br&gt;
      - kafka&lt;br&gt;
    environment:&lt;br&gt;
      - SPRING_PROFILES_ACTIVE=docker&lt;br&gt;
      - DB_PASSWORD=${IDENTITY_DB_PASSWORD}&lt;br&gt;
      - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=&lt;a href="http://service-registry:8761/eureka/" rel="noopener noreferrer"&gt;http://service-registry:8761/eureka/&lt;/a&gt;&lt;br&gt;
      - SPRING_KAFKA_BOOTSTRAPSERVERS=kafka:9092&lt;/p&gt;

&lt;p&gt;doctor-service:&lt;br&gt;
    build: ./doctor-service&lt;br&gt;
    depends_on:&lt;br&gt;
      - postgres-doctor&lt;br&gt;
      - service-registry&lt;br&gt;
      - config-server&lt;br&gt;
      - kafka&lt;br&gt;
    environment:&lt;br&gt;
      - SPRING_PROFILES_ACTIVE=docker&lt;br&gt;
      - DB_PASSWORD=${DOCTOR_DB_PASSWORD}&lt;br&gt;
      - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=&lt;a href="http://service-registry:8761/eureka/" rel="noopener noreferrer"&gt;http://service-registry:8761/eureka/&lt;/a&gt;&lt;br&gt;
      - SPRING_KAFKA_BOOTSTRAPSERVERS=kafka:9092&lt;/p&gt;

&lt;p&gt;# ... similar for other services&lt;/p&gt;

&lt;p&gt;volumes:&lt;br&gt;
  identity-data:&lt;br&gt;
  doctor-data:&lt;br&gt;
  appointment-data:&lt;br&gt;
  billing-data:&lt;br&gt;
  notification-data:&lt;br&gt;
✅ Pros of Microservices&lt;br&gt;
Independent Scaling&lt;/p&gt;

&lt;p&gt;yaml&lt;/p&gt;

&lt;h1&gt;
  
  
  Scale only appointment service during peak hours
&lt;/h1&gt;

&lt;p&gt;docker-compose up -d --scale appointment-service=5&lt;br&gt;
Technology Diversity&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Appointment service can use PostgreSQL&lt;br&gt;
// Notification service can use MongoDB for logs&lt;br&gt;
// Billing service can use Oracle for compliance&lt;br&gt;
Independent Deployment&lt;/p&gt;

&lt;p&gt;Deploy billing service without touching others&lt;/p&gt;

&lt;p&gt;Zero downtime deployments possible&lt;/p&gt;

&lt;p&gt;A/B testing per service&lt;/p&gt;

&lt;p&gt;Fault Isolation&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// If billing service crashes, appointments still work&lt;br&gt;
// Circuit breakers prevent cascading failures&lt;br&gt;
@CircuitBreaker(name = "billing-service")&lt;br&gt;
public Invoice createBill(Appointment appointment) {&lt;br&gt;
    return billingClient.createBill(appointment);&lt;br&gt;
}&lt;br&gt;
Team Autonomy&lt;/p&gt;

&lt;p&gt;Each team owns their service&lt;/p&gt;

&lt;p&gt;Independent release cycles&lt;/p&gt;

&lt;p&gt;Choose their own tools&lt;/p&gt;

&lt;p&gt;❌ Cons of Microservices&lt;br&gt;
Distributed Systems Complexity&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Network calls can fail&lt;br&gt;
// Need retry logic, circuit breakers&lt;br&gt;
// Distributed tracing required&lt;br&gt;
Data Consistency Challenges&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// No ACID transactions across services&lt;br&gt;
// Must implement Saga pattern&lt;br&gt;
// Eventual consistency only&lt;br&gt;
Network Latency&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Previously: method call (1ms)&lt;br&gt;
// Now: REST call (50-100ms)&lt;br&gt;
// Need to optimize API design&lt;br&gt;
Debugging Difficulty&lt;/p&gt;

&lt;p&gt;Logs spread across services&lt;/p&gt;

&lt;p&gt;Need centralized logging&lt;/p&gt;

&lt;p&gt;Correlation IDs essential&lt;/p&gt;

&lt;p&gt;Operational Overhead&lt;/p&gt;

&lt;p&gt;Need DevOps team&lt;/p&gt;

&lt;p&gt;Monitoring required&lt;/p&gt;

&lt;p&gt;Complex deployment pipelines&lt;/p&gt;

&lt;p&gt;🎯 When to Use Microservices&lt;br&gt;
✅ Perfect for:&lt;/p&gt;

&lt;p&gt;Large enterprises with many teams&lt;/p&gt;

&lt;p&gt;Systems needing independent scaling&lt;/p&gt;

&lt;p&gt;Companies with DevOps maturity&lt;/p&gt;

&lt;p&gt;Applications with millions of users&lt;/p&gt;

&lt;p&gt;When different modules need different tech stacks&lt;/p&gt;

&lt;p&gt;❌ Avoid when:&lt;/p&gt;

&lt;p&gt;Small team (&amp;lt; 10 developers)&lt;/p&gt;

&lt;p&gt;Simple application&lt;/p&gt;

&lt;p&gt;Limited DevOps resources&lt;/p&gt;

&lt;p&gt;Startup/MVP phase&lt;/p&gt;

&lt;p&gt;Strict data consistency requirements&lt;/p&gt;

&lt;p&gt;🚀 Recommended Evolution Path&lt;br&gt;
Most successful systems evolve naturally:&lt;/p&gt;

&lt;p&gt;text&lt;br&gt;
Phase 1: MONOLITH&lt;br&gt;
         ↓&lt;br&gt;
Phase 2: MODULAR MONOLITH&lt;br&gt;
         ↓&lt;br&gt;
Phase 3: EXTRACT HIGH-LOAD MODULES&lt;br&gt;
         ↓&lt;br&gt;
Phase 4: MICROSERVICES&lt;br&gt;
Real-World Evolution Example&lt;br&gt;
Year 1-2: Monolith&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Fast development, validate business model&lt;br&gt;
// Hospital OPD system as single Spring Boot app&lt;br&gt;
// Perfect for initial launch&lt;br&gt;
Year 2-3: Modular Monolith&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Business growing, team expanding&lt;br&gt;
// Introduce Spring Modulith&lt;br&gt;
// Clear boundaries, event-driven communication&lt;br&gt;
// Still one deployment&lt;br&gt;
Year 3-4: Extract Billing Module&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Billing has high load, compliance requirements&lt;br&gt;
// Extract as separate microservice&lt;br&gt;
// Others remain modular monolith&lt;br&gt;
// Hybrid architecture&lt;br&gt;
Year 4+: Full Microservices&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Different teams for each domain&lt;br&gt;
// Independent scaling needs&lt;br&gt;
// Full microservices with Kubernetes&lt;br&gt;
📊 Final Comparison Table&lt;br&gt;
Feature Monolith    Modular Monolith    Multi-Module    Microservices&lt;br&gt;
Deployment Units    1   1   1   Multiple&lt;br&gt;
Databases   1 shared    1 shared    1 shared    Separate per service&lt;br&gt;
Communication   In-JVM method calls Method calls + Events   Compile-time deps + method calls    HTTP/REST + Message Queue&lt;br&gt;
Scalability Scale entire app    Scale entire app    Scale entire app    Scale per service&lt;br&gt;
Development Speed (Initial) 🚀 Fast   🚀 Fast   🚀 Fast   🐢 Slow&lt;br&gt;
Development Speed (Long-term)   🐢 Slow   🚀 Fast   🚀 Fast   🚀 Fast&lt;br&gt;
Team Autonomy   Low Medium  Medium  High&lt;br&gt;
Testing Complexity  Low Medium  Medium  High&lt;br&gt;
Operational Complexity  Low Low Low High&lt;br&gt;
Fault Isolation None    Limited None    Excellent&lt;br&gt;
Technology Diversity    None    None    None    Full&lt;br&gt;
Learning Curve  Easy    Medium  Medium  Steep&lt;br&gt;
Best For    MVP, Startups   Growing products    Large codebases Enterprise scale&lt;br&gt;
🧠 Final Advice for Junior Developers&lt;br&gt;
📝 Golden Rules&lt;br&gt;
Don't Start with Microservices!&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Bad: Starting new project with 10 microservices&lt;br&gt;
// Good: Start simple, evolve when needed&lt;br&gt;
Build Clean Boundaries from Day 1&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Even in monolith, think in modules&lt;br&gt;
// Separate concerns, avoid circular dependencies&lt;br&gt;
Understand Your Domain First&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
// Domain-driven design helps&lt;br&gt;
// Bounded contexts become service boundaries later&lt;br&gt;
Choose Based on Team Size&lt;/p&gt;

&lt;p&gt;text&lt;br&gt;
1-5 developers → Monolith or Modular Monolith&lt;br&gt;
5-15 developers → Modular Monolith&lt;br&gt;
15+ developers → Consider microservices&lt;br&gt;
Remember: Amazon, Netflix Started as Monoliths&lt;/p&gt;

&lt;p&gt;They evolved to microservices over years&lt;/p&gt;

&lt;p&gt;They had the team size and expertise&lt;/p&gt;

&lt;p&gt;They had clear business reasons&lt;/p&gt;

&lt;p&gt;🎓 Career Advice&lt;br&gt;
Learn Monolith first - Understand the basics&lt;/p&gt;

&lt;p&gt;Master Modular Monolith - Most common in real jobs&lt;/p&gt;

&lt;p&gt;Understand Multi-Module - For build management&lt;/p&gt;

&lt;p&gt;Study Microservices - For enterprise roles&lt;/p&gt;

&lt;p&gt;💡 The Sweet Spot&lt;br&gt;
For 80% of real-world applications, a Modular Monolith is the perfect choice:&lt;/p&gt;

&lt;p&gt;Clear architecture&lt;/p&gt;

&lt;p&gt;Fast development&lt;/p&gt;

&lt;p&gt;Easy deployment&lt;/p&gt;

&lt;p&gt;Future-proof&lt;/p&gt;

&lt;p&gt;No distributed complexity&lt;/p&gt;

&lt;p&gt;📚 Summary&lt;br&gt;
We've explored four architectures for the same Hospital OPD system:&lt;/p&gt;

&lt;p&gt;Architecture    One-Line Summary&lt;br&gt;
Monolith    Everything in one place, simple but messy&lt;br&gt;
Modular Monolith    One app with strict internal boundaries&lt;br&gt;
Multi-Module    Build-time separation, runtime together&lt;br&gt;
Microservices   Fully distributed, maximum flexibility&lt;br&gt;
Your choice depends on:&lt;/p&gt;

&lt;p&gt;Team size and expertise&lt;/p&gt;

&lt;p&gt;Current stage of project&lt;/p&gt;

&lt;p&gt;Scaling requirements&lt;/p&gt;

&lt;p&gt;Organizational maturity&lt;/p&gt;

&lt;p&gt;🎯 Final Thought&lt;br&gt;
"The best architecture is not the most advanced one, but the one that solves your current problems without creating new ones."&lt;/p&gt;

&lt;p&gt;Start simple, evolve gradually, and always keep your modules cleanly separated. Your future self will thank you!&lt;/p&gt;

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

&lt;p&gt;Found this guide helpful? Share it with fellow developers!&lt;/p&gt;

</description>
      <category>springboot</category>
    </item>
    <item>
      <title>How POSTGRES indexing is more efficient than MYSQL</title>
      <dc:creator>Khairul Basar</dc:creator>
      <pubDate>Tue, 20 Jan 2026 09:46:23 +0000</pubDate>
      <link>https://dev.to/khairul_basar_a2746d66c5f/how-postgres-indexing-is-more-efficient-than-mysql-2ohl</link>
      <guid>https://dev.to/khairul_basar_a2746d66c5f/how-postgres-indexing-is-more-efficient-than-mysql-2ohl</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Problem setup (How Index Scan Internally works for both DBs)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Table in MySQL and PostgreSQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user(
  id   BIGINT PRIMARY KEY,
  name VARCHAR(100),
  age  INT
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX idx_user_name ON user(name);

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT age FROM user WHERE name = 'Rahim';

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Assume:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Table has 10 million rows&lt;/li&gt;
&lt;li&gt;Index is a B-Tree&lt;/li&gt;
&lt;li&gt;name is not unique&lt;/li&gt;
&lt;li&gt;age is not in the index&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1️⃣ MySQL (InnoDB) — Step by step
&lt;/h2&gt;

&lt;p&gt;🔑 Important InnoDB rule&lt;/p&gt;

&lt;p&gt;Secondary index stores the PRIMARY KEY, not the row location&lt;/p&gt;

&lt;p&gt;So idx_user_name looks like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(name, primary_key_id)&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Step-by-step execution
&lt;/h2&gt;

&lt;p&gt;🧭 Step 1: Traverse secondary index (name)&lt;/p&gt;

&lt;p&gt;MySQL searches the B-Tree for 'Rahim'.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Cost: O(log N)&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;B-Tree levels:&lt;br&gt;
&lt;code&gt;Root → Internal → Leaf&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;At the leaf, it finds:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;('Rahim', id=73482)&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;⚠️ It does NOT have age yet&lt;/p&gt;

&lt;p&gt;🧭 Step 2: Traverse PRIMARY KEY index (clustered index)&lt;/p&gt;

&lt;p&gt;In InnoDB:&lt;/p&gt;

&lt;p&gt;Primary key index IS the table&lt;/p&gt;

&lt;p&gt;Rows are physically stored in PK order&lt;/p&gt;

&lt;p&gt;Now MySQL uses id = 73482 to search the PK B-Tree.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Cost: O(log N)&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
At the PK leaf node, it finds the full row:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(id=73482, name='Rahim', age=29)&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  ✅ Total cost (MySQL)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xgztcghtpys1n1xk2i8.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%2F7xgztcghtpys1n1xk2i8.png" alt=" " width="783" height="235"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🔍 Key MySQL characteristics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Clustered index = good locality&lt;/li&gt;
&lt;li&gt;❌ Two tree traversals&lt;/li&gt;
&lt;li&gt;❌ PK lookup cost grows with table size&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  2️⃣ PostgreSQL — Step by step
&lt;/h2&gt;

&lt;p&gt;🔑 Important PostgreSQL rule&lt;/p&gt;

&lt;p&gt;Index stores a TID (tuple ID) → pointer to heap location&lt;/p&gt;

&lt;p&gt;Index entry looks like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(name, (block_id, offset))&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step-by-step execution
&lt;/h2&gt;

&lt;p&gt;🧭 Step 1: Traverse B-Tree index (name)&lt;/p&gt;

&lt;p&gt;PostgreSQL searches index for 'Rahim'.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Cost: O(log N)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;At the leaf, it finds:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;('Rahim', TID=(block=102345, offset=7))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;🧭 Step 2: Heap fetch (direct pointer)&lt;/p&gt;

&lt;p&gt;Postgres now:&lt;/p&gt;

&lt;p&gt;Goes directly to heap page 102345&lt;/p&gt;

&lt;p&gt;Reads row at offset 7&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Cost: O(1) (conceptually)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Row found:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(id=73482, name='Rahim', age=29)&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ✅ Total cost (PostgreSQL)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6cqvgt8fk4wqjzgdakl.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%2Fd6cqvgt8fk4wqjzgdakl.png" alt=" " width="720" height="226"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🔍 Key PostgreSQL characteristics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ One B-Tree traversal&lt;/li&gt;
&lt;li&gt;✅ Heap fetch is constant-time&lt;/li&gt;
&lt;li&gt;❌ Heap pages may be scattered (less locality)&lt;/li&gt;
&lt;li&gt;❌ Extra visibility checks (MVCC)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  3️⃣ Side-by-side comparison (core difference)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3l6216gb9qb9fr2rafy.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%2Fn3l6216gb9qb9fr2rafy.png" alt=" " width="762" height="381"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  4️⃣ Real-world performance (THIS is the key insight)
&lt;/h2&gt;

&lt;p&gt;⚠️ Big-O is not the full story&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When MySQL can be faster&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;PK is small&lt;/li&gt;
&lt;li&gt;Data fits in buffer pool&lt;/li&gt;
&lt;li&gt;Rows are accessed sequentially&lt;/li&gt;
&lt;li&gt;Heavy read workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➡️ Clustered index wins&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When PostgreSQL can be faster&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Very large tables&lt;/li&gt;
&lt;li&gt;Many secondary indexes&lt;/li&gt;
&lt;li&gt;Random access patterns&lt;/li&gt;
&lt;li&gt;Index-only scans possible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➡️ Pointer-based access wins&lt;/p&gt;


&lt;h2&gt;
  
  
  5️⃣ Index-only scan (Postgres secret weapon 🧠)
&lt;/h2&gt;

&lt;p&gt;If you change index to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX idx_user_name_age ON user(name, age);

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT age FROM user WHERE name = 'Rahim';

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

&lt;/div&gt;



&lt;p&gt;🔥 PostgreSQL can return result WITHOUT touching heap at all&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Cost:&lt;br&gt;
O(log N)&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;MySQL cannot do true index-only scan in the same way because:&lt;br&gt;
Secondary index does not contain row version visibility info&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6️⃣ Final verdict (short answer)
&lt;/h2&gt;

&lt;p&gt;📌 Theoretical efficiency&lt;/p&gt;

&lt;p&gt;✅ PostgreSQL is more efficient&lt;/p&gt;

&lt;p&gt;`O(logN) + O(1)&lt;/p&gt;

&lt;p&gt;vs&lt;/p&gt;

&lt;p&gt;O(logN) + O(logN)`&lt;/p&gt;

&lt;h2&gt;
  
  
  📌 Practical efficiency
&lt;/h2&gt;

&lt;p&gt;`Small / medium datasets → MySQL often feels faster&lt;/p&gt;

&lt;p&gt;Large datasets + many indexes → PostgreSQL scales better&lt;/p&gt;

&lt;p&gt;Analytics / complex queries → PostgreSQL wins&lt;/p&gt;

&lt;p&gt;Simple OLTP workloads → MySQL is excellent`&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 One-line intuition
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;MySQL: “Find index → find PK → find row”&lt;br&gt;
Postgres: “Find index → jump straight to row”&lt;/code&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>mysql</category>
      <category>database</category>
      <category>dbms</category>
    </item>
  </channel>
</rss>
