Microservices Design Patterns in Spring Boot 2026

Microservices Design Patterns in Spring Boot 2026

When you’re preparing for microservices architecture interviews at companies like TCS, Infosys, Wipro, or EPAM, understanding microservices design patterns in Spring Boot is non-negotiable. In 2026, these patterns have become the backbone of enterprise Java applications, replacing monolithic systems at scale.

Microservices Design Patterns in Spring Boot 2026

Microservices Design Patterns in Spring Boot 2026

⏱️ 21 min read | 📚 Updated June 2026

💡 Quick Tip: Need fast answers? Jump directly to the FAQ section below.

View Quick Answers ↓

The challenge isn’t just knowing what a microservice is—it’s understanding how to structure them properly. I’ve reviewed hundreds of interview cases where candidates failed because they couldn’t explain why they’d use a Circuit Breaker pattern instead of direct REST calls, or when to implement the Saga pattern for distributed transactions. This post gives you the exact patterns that interviewers ask about, with production-ready code examples from real-world implementations.

By the end of this guide, you’ll be able to design, implement, and defend microservices architectures that handle distributed systems challenges. Let’s start with what actually matters in 2026.

Table of Contents

Why Interviewers Ask About Microservices Design Patterns

Microservices Design Patterns in Spring Boot 2026
Quick visual comparison — Microservices Design Patterns in Spring Boot 2026

Microservices architecture has moved from theoretical to mission-critical at every major tech company. When interviewers ask about microservices design patterns in Spring Boot, they’re testing three things: whether you understand distributed systems complexity, whether you can solve real problems (not just theory), and whether you know production constraints.

At TCS and Infosys, you’ll see these patterns in banking applications handling millions of transactions. At Wipro and EPAM, they’re embedded in client projects for healthcare, fintech, and e-commerce. Startups use them to scale from 100 to 10,000 requests per second without rewriting code. Interviewers ask because they need developers who can implement patterns that prevent cascading failures, handle eventual consistency, and maintain system reliability at scale.

This isn’t theoretical knowledge—it’s the difference between a system that works and a system that survives production incidents.

Quick Comparison of Core Microservices Design Patterns

Pattern Name Problem Solved When to Use Complexity
Circuit Breaker Cascading failures from failing services Service A calls Service B which is down Medium
Service Registry Dynamic service discovery in distributed system 10+ microservices, dynamic scaling Medium
API Gateway Single entry point, authentication, routing Multiple frontend clients, cross-cutting concerns Low
Saga Pattern Distributed transactions across services Order processing, payment flows (eventual consistency) High
Event Sourcing Audit trail, event replay, state reconstruction Financial systems, compliance requirements High
CQRS Read/write optimization, complex queries Read-heavy systems, separate scaling needs High
Bulkhead Pattern Resource isolation, preventing resource exhaustion Multiple critical services, thread pool management Medium

Core Microservices Design Patterns Explained

The Circuit Breaker Pattern

The Circuit Breaker pattern is your first line of defense against cascading failures. Imagine Service A makes a REST call to Service B. If Service B is down, Service A will keep trying, timing out, and burning resources. The Circuit Breaker prevents this by detecting failures and “opening the circuit”—rejecting calls to the failing service temporarily.

In Spring Boot, you implement this with Resilience4j (the industry standard replacing Hystrix). When the circuit is CLOSED, requests pass through normally. When failures exceed a threshold, it OPENS, and requests fail fast. After a timeout, it moves to HALF_OPEN, testing if the service has recovered.

This pattern appears in every microservices interview. At Infosys and TCS, they ask: “How would you prevent a payment service failure from bringing down the entire order system?” Your answer should mention the Circuit Breaker by name and explain how it saves your application from cascading failure.

Service Registry and Discovery Pattern

In a monolithic application, you hardcode server addresses in configuration. In microservices design patterns with Spring Boot, services are ephemeral—containers restart, new instances spin up, old ones shut down. You can’t hardcode IP addresses.

The Service Registry pattern solves this. Services register themselves with a central registry (Eureka, Consul, Kubernetes) when they start. When Service A needs to call Service B, it queries the registry instead of hardcoding an address. This enables automatic failover, load balancing, and dynamic scaling.

Spring Cloud Eureka is the go-to implementation for Spring Boot. During interviews at EPAM and Wipro, candidates often confuse service discovery with load balancing—service discovery tells you WHERE a service is, load balancing decides WHICH instance receives the request. Understanding this distinction matters.

The API Gateway Pattern

Before microservices, you had one backend serving one or two frontend clients. Now you have multiple services, mobile apps, third-party integrations, and web clients. Each frontend shouldn’t know about every backend service. The API Gateway acts as the single entry point, handling authentication, rate limiting, request routing, and response aggregation.

Without an API Gateway, you’ll have duplicate authentication logic, inconsistent error handling, and frontend teams building complicated routing logic. Spring Cloud Gateway is the modern choice (replacing Zuul in 2026). It provides reactive, non-blocking request processing and integrates seamlessly with service discovery.

In interviews, they ask: “Why would you use an API Gateway instead of having clients call services directly?” The answer covers cross-cutting concerns, protocol translation, security, and reduced coupling between frontend and backend teams.

The Saga Pattern for Distributed Transactions

This is where microservices get hard. In a monolith, you wrap operations in a database transaction—all or nothing. In microservices, transactions span multiple databases across multiple services. The Saga pattern solves this using choreography (event-driven) or orchestration (centralized coordinator).

Consider an e-commerce order: you need to reserve inventory, charge the payment, create a shipment, and update analytics. Each lives in a different service. If payment fails, you need to compensate—release inventory, notify the customer, rollback everything. The Saga pattern manages these compensation transactions automatically.

Orchestration (using a Saga Orchestrator service) is more common in enterprise systems because it’s easier to understand and debug. The orchestrator knows the entire flow and decides what happens next. Choreography (using events) is more decoupled but harder to trace when things fail. At TCS and Infosys, they prefer orchestration for financial systems where every step must be auditable.

Top Interview Questions & Answers on Microservices Design Patterns

Q1: What’s the difference between Circuit Breaker and Retry patterns? When would you use both?

Answer: The Retry pattern attempts the same operation multiple times if it fails—useful for transient failures (temporary network glitch). The Circuit Breaker prevents repeated calls to a failing service—useful for systemic failures (service is down for 30 minutes).

You use both together: Retry handles transient failures with exponential backoff (wait 100ms, then 200ms, then 400ms). Circuit Breaker catches persistent failures. Without Retry, you’d open the circuit too quickly on temporary issues. Without Circuit Breaker, your retries would pound a dying service and waste resources.

In Resilience4j Spring Boot code, you chain them: @CircuitBreaker @Retry. The Retry executes first (tries 3 times), then Circuit Breaker evaluates the result. If all retries fail, Circuit Breaker opens. At Infosys, this combination prevents cascading failures while handling real network issues.

Q2: How is Service Registry different from a Load Balancer?

Answer: Service Registry answers “WHERE is the service?” Load Balancer answers “WHICH instance should handle this request?”

A Service Registry (Eureka) maintains a list of healthy service instances. When Service A needs Service B, it queries the registry and gets back 3 IP addresses. Then the client-side load balancer (Ribbon in older Spring Cloud, Spring Cloud Load Balancer now) picks one of those 3 using round-robin or least-connections algorithm.

Some systems use server-side load balancers (like AWS ELB), but in Kubernetes environments, service discovery is built-in and load balancing happens at the network layer. The key difference: registry is about discovery (what exists), load balancer is about distribution (where to send this request). At EPAM, understanding this prevents over-engineering with redundant load balancers.

Q3: Explain Choreography vs. Orchestration in Saga patterns with a real example.

Answer: In Choreography, services communicate through events. Order Service creates an order and publishes “OrderCreated” event. Payment Service listens, processes payment, publishes “PaymentCompleted”. Inventory Service listens and reserves items. If Payment fails, it publishes “PaymentFailed”, Inventory listens and rolls back.

In Orchestration, a Saga Orchestrator service owns the flow. It calls Order Service (create order), then Payment Service (charge card), then Inventory Service (reserve stock). If any step fails, it executes compensating transactions in reverse order.

Choreography is loosely coupled—services don’t know about each other, only events. Orchestration is tightly coupled to the orchestrator but easier to debug because you see the entire flow in one place. For payment processing at TCS and Wipro, orchestration is preferred because you need complete auditability and transaction history. Real example: imagine a flight booking where you need to book flight, hotel, and rental car. Orchestration lets you roll back all three if one fails; choreography requires each service to know compensation logic.

Q4: How do you handle eventual consistency in microservices? Isn’t it risky?

Answer: Eventual consistency means data across services won’t be perfectly synchronized immediately. When a user places an order, the order service shows “Confirmed” but analytics might take 2 seconds to update. This is acceptable for most use cases but risky for financial transactions.

You handle it by: (1) designing compensating transactions (if payment fails later, reverse the order), (2) implementing idempotency keys (if a request is retried, it produces the same result), (3) adding monitoring alerts for inconsistency durations that exceed thresholds, and (4) choosing orchestrated Sagas for critical operations where you need tight control.

At financial institutions (TCS, Infosys), they minimize eventual consistency windows to milliseconds. At startups and EPAM client projects, a 1-2 second window is acceptable. The answer demonstrates you understand the trade-off between consistency and availability (CAP theorem).

Q5: What responsibilities should an API Gateway handle? What should it NOT handle?

Answer: Should handle: Request routing (which service handles this URL), authentication/authorization (validate JWT), rate limiting (max 1000 requests/minute), request/response logging, protocol translation (REST to gRPC), and response aggregation (combine data from multiple services).

Should NOT handle: Business logic (that belongs in microservices), database queries (no direct DB connections), heavy computation (gateway should be thin and fast), or service-to-service communication (that’s internal, goes around the gateway).

The mistake I see in interviews: candidates make the API Gateway too smart, turning it into a bottleneck and single point of failure. Keep it lean. At TCS and Infosys, API Gateways are stateless and horizontally scalable. In Spring Cloud Gateway, you configure routes declaratively in YAML, not in code.

Q6: How would you monitor and trace requests across microservices?

Answer: You use distributed tracing with correlation IDs and centralized logging. When User calls Order Service → Payment Service → Notification Service, each hop adds a trace ID to logs. Tools like Sleuth (Spring Cloud) add trace IDs automatically, and Zipkin/Jaeger visualize the entire request path.

Without distributed tracing, when a request fails, you’d have to check logs on 5 different servers. With it, you click the trace ID and see the entire journey in milliseconds. You’d also implement metrics (response times, error rates) with Micrometer and Prometheus, and structured logging (JSON logs) so log aggregators can parse and search them.

At Wipro and EPAM, distributed tracing is mandatory for any system with 5+ services. Interview answer should mention: correlation IDs, trace visualization, structured logging, and metrics collection as a package.

Q7: How do you secure service-to-service communication in a microservices architecture?

Answer: This is critical for production systems. You have two approaches:

Mutual TLS (mTLS): Services authenticate each other using certificates. Service A presents a certificate to Service B, which validates it. This is the most secure but requires certificate management infrastructure. Kubernetes/Istio handle this automatically with sidecar proxies.

Service-to-Service OAuth/JWT: Service A obtains a JWT token from an auth server, sends it to Service B. Service B validates the JWT signature using a public key. This is lighter-weight than mTLS but requires token refresh logic and key rotation.

In practice, TCS and Infosys use mTLS for critical services (payment processing) and OAuth for internal microservices. At EPAM and startups, mTLS is enforced at the infrastructure level (Istio service mesh) so developers don’t think about it.

Q8: In microservices, should each service have its own database? What are the trade-offs?

Answer: Yes, each service should own its database. This gives you independent scaling, deployment, and technology choices. Service A can use PostgreSQL, Service B can use MongoDB. They scale independently based on their access patterns.

The cost: distributed transactions become hard (hence Saga pattern), data consistency is eventual, and you lose the comfort of JOINs across services. You need events and data replication to share information.

The mistake: sharing a single database across services. This couples services at the database layer, making it impossible to deploy independently or scale individually. At TCS, this anti-pattern is a red flag. A good answer shows you understand both sides—database per service is the goal, but you accept eventual consistency and implement Sagas to manage it.

Production Code Examples

Circuit Breaker Implementation with Resilience4j


import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class PaymentService {
    
    private final RestTemplate restTemplate;
    
    public PaymentService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    
    @CircuitBreaker(
        name = "paymentService",
        fallbackMethod = "paymentFallback"
    )
    public String processPayment(String orderId, double amount) {
        // This call might fail if payment service is down
        String url = "http://payment-service/api/charge";
        return restTemplate.postForObject(
            url,
            new PaymentRequest(orderId, amount),
            String.class
        );
    }
    
    // Fallback method called when circuit opens
    public String paymentFallback(String orderId, double amount, Exception ex) {
        // Log the failure
        System.err.println("Payment service unavailable for order: " + orderId);
        
        // Return cached response or queue for retry
        return "PAYMENT_PENDING_RETRY";
    }
}

Explanation: The @CircuitBreaker annotation monitors the processPayment method. If it throws exceptions exceeding a threshold (default: 50% failure rate over 10 requests), the circuit OPENS. New calls immediately invoke the fallback method without hitting the failing service. After a timeout period (default: 30 seconds), the circuit moves to HALF_OPEN and tests one request. If it succeeds, the circuit CLOSES. This prevents your order service from hammering a dead payment service.

Configuration in application.yml:


resilience4j:
  circuitbreaker:
    instances:
      paymentService:
        slidingWindowSize: 10
        failureRateThreshold: 50
        waitDurationInOpenState: 30000
        permittedNumberOfCallsInHalfOpenState: 3

Saga Orchestration Pattern Example


import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

@Service
public class OrderSagaOrchestrator {
    
    @Autowired
    private OrderService orderService;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private NotificationService notificationService;
    
    public OrderResponse executeOrderSaga(OrderRequest request) {
        Order order = null;
        Payment payment = null;
        
        try {
            // Step 1: Create order
            order = orderService.createOrder(request);
            System.out.println("✓ Order created: " + order.getId());
            
            // Step 2: Process payment
            payment = paymentService.chargeCustomer(
                order.getId(),
                order.getTotalAmount()
            );
            System.out.println("✓ Payment processed: " + payment.getTransactionId());
            
            // Step 3: Reserve inventory
            inventoryService.reserveInventory(order.getId(), request.getItems());
            System.out.println("✓ Inventory reserved");
            
            // Step 4: Send confirmation
            notificationService.sendOrderConfirmation(order.getCustomerEmail());
            System.out.println("✓ Confirmation sent");
            
            order.setStatus("CONFIRMED");
            orderService.updateOrder(order);
            return new OrderResponse(order.getId(), "SUCCESS", "Order confirmed");
            
        } catch (PaymentException e) {
            // Compensate: revert order on payment failure
            System.err.println("✗ Payment failed: " + e.getMessage());
            if (order != null) {
                orderService.cancelOrder(order.getId());
            }
            notificationService.sendFailureNotification(
                request.getCustomerEmail(),
                "Payment processing failed"
            );
            return new OrderResponse(null, "FAILED", "Payment failed: " + e.getMessage());
            
        } catch (InventoryException e) {
            // Compensate: refund payment and cancel order
            System.err.println("✗ Inventory unavailable: " + e.getMessage());
            if (payment != null) {
                paymentService.refund(payment.getTransactionId());
            }
            if (order != null) {
                orderService.cancelOrder(order.getId());
            }
            notificationService.sendFailureNotification(
                request.getCustomerEmail(),
                "Items out of stock"
            );
            return new OrderResponse(order.getId(), "FAILED", "Inventory unavailable");
        }
    }
}

Explanation: This Saga Orchestrator manages the entire order flow. Each step is a separate service call. If payment fails, it immediately rolls back (compensation), canceling the order and notifying the customer. If inventory fails after payment succeeds, it refunds the payment BEFORE canceling the order. This guarantees consistency despite failures in individual services. The orchestrator is the single source of truth for the entire order flow, making it easy to audit and debug at companies like TCS.

API Gateway Configuration with Spring Cloud Gateway


import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ApiGatewayConfig {
    
    @Bean
    public RouteLocator customRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
            // Route to Order Service
            .route("order-service", r -> r
                .path("/api/orders/**")
                .filters(f -> f
                    .rewritePath("/api/orders(?/?.*)", "/orders${segment}")
                    .addRequestHeader("X-Request-ID", 
                        String.valueOf(System.currentTimeMillis()))
                    .requestRateLimiter(c -> c
                        .setRateLimiter(redisRateLimiter())
                        .setKeyResolver(userKeyResolver()))
                )
                .uri("lb://order-service")
            )
            // Route to Payment Service
            .route("payment-service", r -> r
                .path("/api/payments/**")
                .filters(f -> f
                    .rewritePath("/api/payments(?/?.*)", "/payments${segment}")
                    .addRequestHeader("X-Service", "api-gateway")
                )
                .uri("lb://payment-service")
            )
            // Route to Inventory Service
            .route("inventory-service", r -> r
                .path("/api/inventory/**")
                .filters(f -> f
                    .rewritePath("/api/inventory(?/?.*)", "/inventory${segment}")
                )
                .uri("lb://inventory-service")
            )
            .build();
    }
    
    @Bean
    public KeyResolver userKeyResolver() {
        // Rate limit by user ID from JWT token
        return exchange -> Mono.just(
            exchange.getRequest()
                .getHeaders()
                .getOrDefault("X-User-ID", "anonymous")
                .stream()
                .findFirst()
                .orElse("anonymous")
        );
    }
}

Explanation: This configuration routes all requests to `/api/orders/**` to the Order Service (discovered via service registry `lb://order-service`), `/api/payments/**` to Payment Service, and so on. Each route is filtered to add request headers, rewrite paths, and enforce rate limiting. Clients never know about individual services—they only call the gateway at `api-gateway:8080`. This is the pattern used at Infosys and Wipro to manage 50+ microservices behind a single entry point.

Common Mistakes to Avoid in Microservices Design Pattern Interviews

  • Not mentioning circuit breakers: Saying “we use REST to call other services” without mentioning fault tolerance. Always pair REST communication with Circuit Breaker pattern. This is the #1 red flag for junior developers.
  • Assuming strong consistency is possible: Designing transactions across services as if they were database transactions. Microservices require eventual consistency and Saga patterns, not distributed ACID transactions. This shows you don’t understand the CAP theorem.
  • Sharing databases across services: Saying “all services read from one database for consistency” defeats the purpose of microservices. Each service owns its data. Accept eventual consistency and implement proper patterns.
  • Forgetting about monitoring and observability: Designing a system without mentioning distributed tracing, metrics, or centralized logging. In a system with 20 services, you can’t debug without these tools.
  • Overcomplicating with too many patterns: Trying to implement Saga + CQRS + Event Sourcing when a simple REST API with Circuit Breaker would work. Use patterns only when the problem demands it. CQRS adds complexity; use it only when reads and writes have vastly different requirements.
  • Not discussing API Gateway benefits: Saying services can call each other directly without mentioning cross-cutting concerns (auth, logging, rate limiting) that require a gateway. This indicates you haven’t managed multiple frontend clients.
  • Confusing service discovery with load balancing: These are separate concerns. Service discovery says “Service B exists at 10.0.0.2, 10.0.0.3, 10.0.0.4”. Load balancing decides “send this request to 10.0.0.3”. Getting this wrong suggests you haven’t deployed distributed systems.
  • Ignoring idempotency in retries: If a request fails and you retry it, the same request might be processed twice. You must ensure idempotency (using idempotency keys) to prevent double payments or duplicate orders. At financial companies, this is critical.

Best Practices for Acing Microservices Design Pattern Interviews

  1. Always start with the problem, not the pattern. Don’t say “we use the Saga pattern.” Say “we have payments, inventory, and shipping as separate services. If payment fails, we need to roll back inventory and refund the customer. The Saga pattern solves this by managing compensation transactions automatically.”
  2. Mention production constraints in every answer. Discuss what happens when the service is down, when the network is slow, when you have 100,000 requests per second. Theory without production reality is incomplete. Reference companies like TCS that handle 1M+ daily transactions.
  3. Use specific Spring Boot libraries. Say “Resilience4j for Circuit Breaker” not “some library for fault tolerance.” Say “Spring Cloud Gateway” not “some API gateway.” Knowing the actual tools shows you’ve worked with them.
  4. Draw diagrams or describe the flow step-by-step. Interviewers want to see you think sequentially. “When Order Service receives a request, it creates an order in step 1, calls Payment Service in step 2, calls Inventory Service in step 3. If step 2 fails, we execute compensation in step 2 and step 1.”
  5. Discuss trade-offs explicitly. For every pattern, mention what you gain and what you lose. “Event Sourcing gives us a complete audit trail but requires event store management and eventual consistency.” This shows architectural maturity.
  6. Prepare for “what would you do differently” questions. Interviewers will ask: “If you were designing payment processing for 10,000 transactions per second, would you still use orchestrated Saga?” Be ready with nuanced answers based on scale.
  7. Know the difference between frameworks. Understand why Spring Cloud is for monolithic-to-microservices migration, while Kubernetes/Istio is for cloud-native deployments. Spring Cloud and Kubernetes solve overlapping problems differently.
  8. Mention monitoring from day one. When designing the order system, don’t wait for a monitoring question. Proactively say: “We’d add distributed tracing with Sleuth/Zipkin and metrics with Micrometer so we can understand failure modes in production.”

Final Recommendations

Microservices architecture is no longer optional knowledge—it’s table stakes for Java developers in 2026. Whether you’re interviewing at TCS for enterprise banking systems, Infosys for government modernization, Wipro for retail platforms, or EPAM for client services, you’ll face questions on microservices design patterns in Spring Boot.

The difference between a strong candidate and a weak one isn’t knowing more patterns—it’s understanding when NOT to use them. A strong candidate at Infosys would say: “We use an API Gateway because 5 different frontend teams consume our services and we need centralized authentication. We use Circuit Breaker because payment service fails intermittently and we can’t let those failures bring down orders. We use Saga orchestration because financial transactions require visible audit trails.”

A weak candidate says: “Microservices need Circuit Breaker, API Gateway, and Saga patterns because they’re best practices.” There’s no reasoning, no problem connection, no consideration of trade-offs.

Your next step: Build a small project with Spring Boot that implements 3-4 patterns. Create an Order Service, Payment Service, and Inventory Service. Add a Circuit Breaker between Order and Payment. Add an API Gateway in front. Implement a Saga orchestrator for the flow. Deploy it locally with Docker. When you can deploy and debug these patterns hands-on, interview questions become natural conversations, not memorized answers.

At JavaInterviewQuestionsPro Premium, we provide mock interviews where industry experts ask exactly these questions and grade your answers on technical depth, production thinking, and communication clarity. That’s the practice format companies like TCS actually use in final rounds.

Frequently Asked Questions

Q: Should I learn Kubernetes before microservices design patterns?

No. Understand microservices design patterns first—Circuit Breaker, Saga, Service Registry, API Gateway. Then learn Kubernetes, which is one way to deploy microservices. Spring Boot with Spring Cloud can run on Kubernetes, Docker, EC2, or on-premise servers. The patterns are platform-agnostic; Kubernetes is the deployment platform. At TCS and Infosys, developers know patterns first, then DevOps handles Kubernetes. But if you’re in a smaller team, learn both.

Q: Is Event Sourcing mandatory for microservices?

No. Event Sourcing (storing state as a sequence of immutable events instead of current state) is valuable for audit requirements and event replay, but it’s optional. Use it when you need: complete transaction history (financial systems), compliance requirements (healthcare), or the ability to recompute state at any point in time. At startups and most companies, regular database-per-service with event-driven communication (via messages or events) is sufficient. EPAM uses Event Sourcing only when clients specifically require it.

Q: What’s the difference between choreography and orchestration, and which is better?

Choreography (services publish events and listen for events) is loosely coupled—services don’t know about each other. Orchestration (central orchestrator calls services in sequence) is tightly coupled to the orchestrator but easier to visualize and debug. For critical flows like payments, orchestration is better because you can see the entire transaction. For non-critical flows like analytics, choreography is lighter. At TCS and Wipro, financial systems use orchestration; analytics systems use choreography.

Q: Can I use REST for all microservice communication?

Technically yes, practically no. REST with Circuit Breaker is fine for synchronous request-response flows (Order Service calling Payment Service). But for asynchronous, eventual consistency scenarios (Order created → send confirmation email → update analytics), use message queues (RabbitMQ, Kafka). REST is request-response; queues are one-way notifications. Mixing them increases latency. At Infosys, REST is used for user-facing requests; Kafka is used for internal event processing.

Q: How do you handle database schema changes in a microservices world?

Each service owns its schema—no shared database, so schema changes don’t affect other services. If Service A changes its API (adds a new field), it must be backward compatible so old clients still work. Use semantic versioning (v1, v2) and deprecation periods. At EPAM, they maintain API version endpoints for 6 months before sunsetting old versions. This requires API versioning in your gateway or REST endpoints.

Q: Should services communicate synchronously (REST) or asynchronously (events)?

Use synchronous (REST) when you need immediate response and tight coupling is acceptable (user clicks “Place Order” button—they wait for instant response). Use asynchronous (events/queues) when you can tolerate delays and need loose coupling (order created → send email after 1 second, update analytics after 5 seconds). At TCS, critical user paths use synchronous REST with Circuit Breaker; background operations use asynchronous Kafka. If you try to do everything asynchronously, your system becomes harder to reason about.

Q: How do you test microservices in development? Do you need all services running?

No. Use mocking and stubs for dependent services. Your Order Service test should mock the Payment Service response, not require a real Payment Service instance. For integration tests, use Docker Compose to spin up all services locally. At Infosys and Wipro, developers run `docker-compose up` once and have a full environment. For CI/CD pipelines, containerized services are standard. Use contract testing (Pact framework) to ensure services honor each other’s API contracts without deploying the full system.

Q: What happens if the API Gateway becomes a bottleneck?

Scale the gateway horizontally—run 5 instances behind a load balancer. The gateway is stateless, so adding instances is straightforward. Monitor gateway latency; if it exceeds 50ms, you’ve found your bottleneck. Often the bottleneck is downstream (database or slow service), not the gateway itself. At Wipro handling 100,000 requests/sec, the gateway runs on 10 instances with automated scaling based on CPU. Keep the gateway thin (routing, auth, rate limiting only) and fast—let services handle business logic.

Also read our Java basics interview questions.

Also read our Java advanced interview questions.

Also read our book a mock interview.

Quick Reference

Aspect Key Point
When to use Depends on access pattern and thread safety needs
Interview tip Always explain time/space complexity with a real example

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *