Skip to main content

10 AI Prompts for Designing Java Microservices

10 copy-paste AI prompts for designing Java microservices. Covers OpenAPI contract design, Circuit Breaker with Resilience4j, Kafka producer and consumer, distributed tracing with Micrometer, Kubernetes health probes, idempotency, event-driven sagas, service-to-service OAuth2 authentication, rate limiting, and full design reviews.

Microservices architecture introduces a class of problems that monoliths simply do not have: partial failures, distributed transactions, network latency between services, schema versioning across independent deployments, and the operational complexity of coordinating dozens of independently deployed components. The first time I designed a circuit breaker configuration for a production service, I guessed the thresholds. The circuit opened too aggressively during a transient network hiccup and caused more downtime than the downstream failure it was meant to protect against. The second time, I ran the numbers from the downstream service’s SLA and worked backwards. There was no tutorial that taught me to do that — I learned it the hard way. These 10 prompts encode the questions you need to answer before you configure Resilience4j, write an OpenAPI contract, or design a Kafka consumer group — so the AI produces configuration that fits your actual failure scenario rather than a generic example. Getting these patterns right requires both architectural experience and fluency with a large surface area of libraries and specifications. AI assistants are well-positioned here — they know the Resilience4j API, the OpenAPI specification, the Kafka consumer group model, the Micrometer tracing API, and the Kubernetes health probe semantics.

This post gives you 10 copy-paste AI prompts for designing Java microservices. Each prompt targets a specific cross-cutting architecture concern and is engineered to produce production-grade, runnable output rather than pseudocode.

For related reading, see 10 AI Prompts for Spring Boot Development and the Java series. For the Spring AI and LLM Gateway patterns, see the LLM Gateway for Java Microservices post.

Why These Prompts Ask for So Much Context

Generic microservice prompts produce generic boilerplate. “Implement a circuit breaker” produces Resilience4j code with default thresholds that may be completely wrong for your downstream service’s actual behavior. Each prompt in this post asks you to provide your service name, the specific failure scenario you are designing for, and the concrete library versions you are using. That context is what turns AI output from tutorial code into production configuration.

For Resilience4j and Micrometer prompts, specify the exact versions — the APIs differ between Resilience4j 1.x and 2.x, and the Micrometer instrumentation model changed in Micrometer 2.x (Spring Boot 3.x). A prompt that doesn’t anchor to versions will produce code that may compile against the wrong API.

Prompt 1: Design an OpenAPI Contract

When to use: You are starting a new microservice and want to design the API contract before writing implementation code (contract-first design). A well-specified OpenAPI document becomes the source of truth for client SDK generation, mock server setup, and API gateway configuration.

Design a complete OpenAPI 3.1 contract for the following microservice.

Service description:
[DESCRIBE THE SERVICE, e.g. "An Order Service that manages the lifecycle of customer orders: creation, status transitions (PENDING→CONFIRMED→SHIPPED→DELIVERED), cancellation, and retrieval with filtering by status and date range."]

Business rules:
[LIST KEY RULES, e.g.:
- An order can only be cancelled if its status is PENDING or CONFIRMED
- An order must have at least one item
- Each item quantity must be between 1 and 100
- Total order value must not exceed 10,000.00]

Generate the full OpenAPI 3.1 YAML including:

1. info: section with version, title, description, contact
2. servers: section with environment URLs (production, staging, local)
3. For each endpoint:
   - Path and HTTP method
   - Summary and description (explain the business operation, not just the HTTP verb)
   - Request body schema with all validation constraints (minLength, maximum, pattern, required)
   - Response schemas: 200/201 for success, 400 for validation failure, 404 for not found, 409 for business rule conflict, 500 for unexpected errors
   - All responses use the RFC 9457 ProblemDetail schema
4. components/schemas: reusable schema definitions for all request/response objects
5. components/responses: reusable response definitions for common error types
6. components/parameters: reusable path and query parameter definitions
7. Security scheme: Bearer JWT authentication (securitySchemes + global security requirement)
8. Pagination pattern: cursor-based or offset-based for list endpoints (choose and justify)

After the YAML, show:
- The springdoc-openapi Maven dependency to serve this spec from /api-docs
- How to generate a type-safe Java client from this spec using openapi-generator-maven-plugin

Prompt 2: Implement Circuit Breaker with Resilience4j

When to use: Your microservice calls a downstream service that is occasionally slow or unavailable, and you want to implement the Circuit Breaker pattern to fail fast, protect your thread pool from being exhausted by a slow downstream, and recover automatically when the dependency recovers.

Implement the Circuit Breaker pattern for the following downstream service call using Resilience4j.

Service making the call: [e.g. OrderService]
Downstream dependency: [e.g. PaymentService, called via REST at https://payment-service/api/v1/charges]
Current implementation (the method that calls the downstream):
[PASTE YOUR CURRENT METHOD HERE]

Failure behaviour requirements:
- Open the circuit after: [e.g. 50% failure rate over the last 10 calls]
- Wait before attempting recovery: [e.g. 30 seconds in OPEN state]
- Half-open probe calls: [e.g. allow 3 calls in HALF_OPEN, require all 3 to succeed to CLOSE]
- Fallback when circuit is OPEN: [e.g. "return a cached payment status if available, otherwise throw PaymentUnavailableException"]
- Timeout per call: [e.g. 3 seconds — slow calls count as failures]

Generate:
1. Resilience4j CircuitBreaker configuration (application.yml or @Bean):
   - failureRateThreshold, waitDurationInOpenState, permittedNumberOfCallsInHalfOpenState
   - slowCallRateThreshold, slowCallDurationThreshold (slow calls = failures)
   - record-exceptions list (which exceptions trigger the failure count)
   - ignore-exceptions list (e.g., validation exceptions should NOT open the circuit)

2. @CircuitBreaker(name="paymentService", fallbackMethod="chargePaymentFallback") on the method
   - The fallback method signature (must match the primary method + CallNotPermittedException parameter)
   - Fallback logic implementation

3. Add @Retry(name="paymentService") stacked with @CircuitBreaker:
   - Retry on transient errors (connection reset, 503) but NOT on business errors (400, 409)
   - maxAttempts=3, waitDuration=500ms, exponentialBackoffMultiplier=2

4. Add @TimeLimiter(name="paymentService") to enforce the per-call timeout

5. CircuitBreakerEventListener @Bean that logs state transitions (CLOSED→OPEN→HALF_OPEN) at WARN level

6. Spring Boot Actuator endpoint to expose circuit breaker state: /actuator/circuitbreakers

7. A @SpringBootTest that verifies:
   - The fallback is called when the downstream returns 5xx
   - The circuit opens after the configured failure threshold
   - The circuit closes after successful half-open probe calls

Maven dependency block for resilience4j-spring-boot3.

Prompt 3: Write Kafka Producer and Consumer

When to use: You need to integrate a microservice with Apache Kafka for asynchronous event publishing or consumption, and you want production-quality configuration — correct serialisation, consumer group isolation, error handling with a dead-letter topic, and exactly-once semantics where required.

Implement a Kafka producer and consumer for the following event in a Spring Boot 3.x microservice.

Event description:
[DESCRIBE THE EVENT, e.g. "OrderPlacedEvent — published by OrderService when an order transitions to CONFIRMED status. Consumed by InventoryService (reserve stock) and NotificationService (send confirmation email)."]

Kafka configuration:
- Broker: [e.g. localhost:9092 / Confluent Cloud / AWS MSK]
- Topic name: [e.g. order.placed]
- Partitions: [e.g. 12 — allows 12 parallel consumers]
- Replication factor: [e.g. 3]
- Ordering requirement: [e.g. "events for the same orderId must be processed in order" — use orderId as partition key]
- Delivery guarantee: [at-least-once / exactly-once]

Generate:

PRODUCER (in OrderService):
1. OrderPlacedEvent Java record with all event fields
2. KafkaTemplate<String, OrderPlacedEvent> producer configuration:
   - Serialiser: JsonSerializer (spring-kafka)
   - acks=all (wait for all replicas to acknowledge)
   - retries=3, retry.backoff.ms=1000
   - enable.idempotence=true (prevents duplicate messages on retry)
3. OrderEventPublisher @Service that:
   - Sends the event with orderId as the partition key (guarantees ordering per order)
   - Uses CompletableFuture / KafkaTemplate.send().whenComplete() to handle send failures
   - Logs success (topic, partition, offset) and failure (with the event details for debugging)

CONSUMER (in InventoryService):
4. @KafkaListener configuration:
   - topics = "order.placed", groupId = "inventory-service"
   - concurrency = "[N]" (set to the partition count for maximum parallelism)
   - containerFactory with manual acknowledgement (AckMode.MANUAL_IMMEDIATE)
5. Consumer method with @Payload, @Header extraction
6. Dead Letter Topic (DLT) configuration:
   - Route permanently failing messages (after 3 retries) to order.placed.DLT
   - Use DefaultErrorHandler with FixedBackOff(1000, 3)
7. application.yml Kafka consumer and producer properties
8. @EmbeddedKafka integration test that verifies the full producer → consumer → DLT flow

Prompt 4: Add Distributed Tracing with Micrometer

When to use: Debugging a slow or failing request across multiple microservices is currently impossible because there is no way to correlate logs from different services to the same originating request. You want to add distributed tracing so a single traceId appears in logs, metrics, and spans across every service in the call chain.

Add distributed tracing to the following Spring Boot 3.x microservices using Micrometer Tracing.

Services involved:
[LIST SERVICES, e.g. API Gateway → OrderService → PaymentService → NotificationService]

Tracing backend: [Zipkin / Jaeger / OpenTelemetry Collector]
Spring Boot version: 3.x (use Micrometer Tracing, NOT Spring Cloud Sleuth — Sleuth is deprecated)

For EACH service, generate:

1. Maven dependencies:
   - micrometer-tracing-bridge-otel (or brave for Zipkin)
   - opentelemetry-exporter-zipkin / opentelemetry-exporter-otlp
   - spring-boot-starter-actuator (required for tracing to function)

2. application.yml:
   - management.tracing.sampling.probability=1.0 (100% sampling in dev; 0.1 in prod)
   - management.zipkin.tracing.endpoint (or OTLP endpoint)
   - logging.pattern.level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
     (adds traceId and spanId to every log line automatically)

3. Trace propagation through HTTP headers:
   - Spring Boot 3.x propagates W3C TraceContext (traceparent header) automatically via RestTemplate / WebClient — confirm this is configured and show the RestTemplate @Bean that has the tracing instrumentation

4. Trace propagation through Kafka messages:
   - Show how to propagate traceId in Kafka message headers using KafkaPropagator

5. Custom span creation for business operations:
   - @NewSpan on a service method to create a child span for a significant operation
   - Manually adding business attributes to a span:
     Span.current().tag("order.id", orderId).tag("order.status", status.name());

6. Baggage propagation:
   - Show how to propagate a userId through the entire call chain using BaggageField
   - Useful for correlating all spans of a user's session across services

7. Grafana Tempo + Loki configuration snippet to correlate traces with logs by traceId

Prompt 5: Configure Kubernetes Health Probes

When to use: Your service is restarting too aggressively (liveness probe too sensitive), or traffic is being routed to pods that are not yet warmed up (readiness probe missing), or a dependent service going down is causing your pod to be killed unnecessarily.

Configure Kubernetes health probes and Spring Boot Actuator health groups for the following microservice.

Service characteristics:
- Spring Boot version: 3.x
- Startup time: [e.g. ~15 seconds to be fully ready under normal conditions]
- External dependencies: [e.g. PostgreSQL (required), Redis (optional — graceful degradation), PaymentService REST API (optional)]
- JVM warmup requirement: [e.g. first 30 seconds of traffic should not count as failures]

SPRING BOOT SIDE — generate application.yml:
1. management.endpoint.health.probes.enabled=true
2. Liveness group: includes only livenessState component
   - ONLY reflects whether the JVM is in a broken state (deadlock, OOM, irrecoverable error)
   - Does NOT include database or external service health — a failed database should not kill the pod
3. Readiness group: includes readinessState + database + Redis
   - Redis with fallback: if Redis is DOWN, readiness remains UP (degrade gracefully, do not block traffic)
   - External PaymentService: do NOT include — its failure should not make our pod unready
4. Custom health indicator for the database (show with a timeout so a slow DB query does not block the probe)

KUBERNETES SIDE — generate the Deployment YAML snippet:
5. startupProbe:
   - Path: /actuator/health/liveness
   - failureThreshold: 20, periodSeconds: 5 (allows 100 seconds for startup — covers slow starts)
   - Use startupProbe to protect against premature liveness checks during slow startup

6. livenessProbe:
   - Path: /actuator/health/liveness
   - initialDelaySeconds: 0 (startupProbe handles the delay)
   - periodSeconds: 10, failureThreshold: 3 (restart after 30 seconds of failed liveness)
   - timeoutSeconds: 5

7. readinessProbe:
   - Path: /actuator/health/readiness
   - periodSeconds: 5, failureThreshold: 3 (remove from load balancer after 15 seconds)
   - successThreshold: 2 (require 2 consecutive successes to re-add to load balancer after recovery)
   - timeoutSeconds: 3

8. Graceful shutdown: show the preStop hook + terminationGracePeriodSeconds configuration that allows in-flight requests to complete before the pod is terminated

Prompt 6: Implement Idempotent API Endpoints

When to use: Clients retry failed requests (due to network timeouts, Resilience4j retries, or mobile app reconnects), and you want to ensure that retrying an already-successful operation — like creating an order or charging a payment — does not create duplicate records or charge a customer twice.

Implement idempotent POST endpoints for the following Spring Boot 3.x REST API.

Non-idempotent endpoints to make idempotent:
[LIST THE ENDPOINTS, e.g.:
- POST /api/v1/orders — creates an order; must not create duplicates on retry
- POST /api/v1/payments/charge — charges a payment card; must not double-charge on retry]

Idempotency mechanism: Idempotency-Key header (industry standard, used by Stripe, Braintree)

Generate:
1. Idempotency-Key header specification in OpenAPI (required header on all mutating endpoints)

2. IdempotencyKeyFilter or @Aspect that:
   - Extracts Idempotency-Key from the request header (reject with 400 if missing on POST endpoints)
   - Validates the key format (UUID v4, reject with 400 if malformed)
   - Checks Redis/database for a stored response for this key
   - If found: return the stored response immediately (do not re-execute the handler)
   - If not found: execute the handler, store the response with TTL=24h, then return the response
   - Handle concurrent requests with the same key: use Redis SETNX to acquire a lock

3. IdempotencyRecord entity / Redis hash:
   - idempotencyKey (PK)
   - requestHash (SHA-256 of request body — detect if client sends same key with different body → 422)
   - responseStatus (HTTP status code)
   - responseBody (serialised JSON)
   - createdAt
   - expiresAt (24 hours after creation)

4. Service layer changes:
   - The service method should remain unaware of idempotency — the filter handles it
   - Show how @Transactional on the service method interacts with the idempotency filter

5. A @SpringBootTest that verifies:
   - First call creates the resource and stores the idempotency record
   - Second call with the same key returns the stored response WITHOUT calling the service again (verify with Mockito)
   - A call with the same key but a different body returns 422

Prompt 7: Design an Event-Driven Saga

When to use: A business operation spans multiple microservices — creating an order, reserving inventory, and charging payment — and you need to ensure consistency across all three even when any one of them fails, without using a distributed transaction (2PC).

Design a choreography-based saga for the following multi-service business transaction.

Business operation:
[DESCRIBE THE OPERATION, e.g. "Place an order: (1) OrderService creates the order in PENDING state, (2) InventoryService reserves the items, (3) PaymentService charges the customer. If any step fails, all previous steps must be compensated."]

Services and their local transactions:
[LIST EACH SERVICE AND ITS LOCAL TRANSACTION, e.g.:
- OrderService: create order (PENDING) → on success emit OrderPlacedEvent; on compensation emit OrderCancelledEvent and set status=CANCELLED
- InventoryService: reserve items → on success emit StockReservedEvent; on failure emit StockReservationFailedEvent; compensation: release reservation and emit StockReleasedEvent
- PaymentService: charge card → on success emit PaymentChargedEvent; on failure emit PaymentFailedEvent; compensation: refund and emit PaymentRefundedEvent]

Kafka topic naming: [e.g. order.placed, stock.reserved, stock.reservation.failed, payment.charged, payment.failed]

Generate:

1. All event classes (Java records) with: eventId (UUID), correlationId (the original orderId), timestamp, and event-specific fields

2. For each service, the @KafkaListener handler that:
   - Listens to upstream events
   - Performs the local transaction
   - Publishes the appropriate success or failure event
   - Handles idempotency: uses eventId to detect and skip already-processed events

3. Compensation handlers: each service listens to downstream failure events and executes the compensating transaction

4. Saga state tracking in OrderService:
   - SagaState entity that tracks the correlation ID and current step (for visibility and debugging)
   - Updated by OrderService as events arrive

5. A sequence diagram (as ASCII art or Mermaid) showing the happy path and the inventory-failure path

6. Dead Letter Topic handling: if a compensation message itself fails — what happens? (Manual intervention, alert, idempotent retry)

Prompt 8: Implement Service-to-Service Authentication

When to use: Your microservices communicate over HTTP and you need to ensure that only authorised services can call each other’s internal APIs — preventing a scenario where a compromised public-facing service can call any internal endpoint with no authentication check.

Implement service-to-service authentication for the following microservices using OAuth2 Client Credentials flow.

Authentication server: [e.g. Keycloak 24 / Auth0 / AWS Cognito]
Calling service: [e.g. OrderService]
Called service: [e.g. PaymentService]
Spring Boot version: 3.x

Generate:

CALLING SERVICE (OrderService) — OAuth2 client:
1. Maven dependency: spring-boot-starter-oauth2-client
2. application.yml:
   spring.security.oauth2.client.registration.payment-service:
     client-id, client-secret, scope, authorization-grant-type: client_credentials
   spring.security.oauth2.client.provider.payment-service:
     token-uri: [authorization-server-token-endpoint]
3. OAuth2AuthorizedClientManager @Bean (for programmatic token management)
4. WebClient @Bean configured with ServerOAuth2AuthorizedClientExchangeFilterFunction:
   - Automatically acquires and attaches Bearer tokens
   - Automatically refreshes tokens before expiry (no manual token management)
5. PaymentServiceClient that uses the configured WebClient

CALLED SERVICE (PaymentService) — resource server:
6. Maven dependency: spring-boot-starter-oauth2-resource-server
7. application.yml: spring.security.oauth2.resourceserver.jwt.jwk-set-uri
8. SecurityFilterChain that:
   - Validates JWT Bearer tokens on all /api/v1/internal/** endpoints
   - Requires the scope "payment:charge" for POST /api/v1/charges
   - Rejects all other requests with 401
9. A method-level @PreAuthorize("hasAuthority('SCOPE_payment:charge')") example

TOKEN CACHING:
10. Explain how Spring's OAuth2AuthorizedClientManager caches tokens and refreshes them automatically — developers do not need to manage token lifecycle manually

TESTING:
11. @SpringBootTest with WireMock stubbing the authorization server token endpoint
12. How to use spring-security-test's @WithMockUser equivalent for OAuth2 resource server tests: @WithMockJwt

Prompt 9: Add Rate Limiting to an API Gateway

When to use: A single misbehaving client is consuming a disproportionate share of your API’s capacity, or you need to enforce different rate limits for free vs paid tiers, or you want to protect a downstream service from traffic spikes that it cannot absorb.

Implement rate limiting for the following Spring Cloud Gateway or Spring Boot REST API.

Gateway type: [Spring Cloud Gateway / Spring Boot with Bucket4j / Kong / AWS API Gateway]
Rate limiting strategy: [per-IP / per-authenticated-user / per-API-key / per-client-tier]

Rate limits to enforce:
[DEFINE TIERS, e.g.:
- Anonymous / unauthenticated: 10 requests/minute per IP
- Free tier users: 100 requests/minute per userId
- Pro tier users: 1,000 requests/minute per userId
- Internal service-to-service: unlimited (bypass rate limiting for requests with a valid service JWT)]

For Spring Cloud Gateway approach, generate:
1. Maven dependency: spring-cloud-starter-gateway + spring-boot-starter-data-redis-reactive
2. application.yml route configuration with:
   - RequestRateLimiter filter using RedisRateLimiter
   - KeyResolver bean that extracts userId from JWT claims (or IP for unauthenticated)
   - Separate rate limit configs per route/tier
3. RateLimiter @Bean: RedisRateLimiter(replenishRate, burstCapacity, requestedTokens)
4. Custom KeyResolver that:
   - For authenticated requests: extracts userId from Authorization header JWT
   - For service-to-service: returns "unlimited" key (bypasses limiter)
   - For anonymous: returns the client IP

For Bucket4j approach (embedded, no gateway), generate:
5. Bucket4j-spring-boot-starter configuration
6. @RateLimiting annotation on controller methods
7. Redis backend for distributed rate limiting (so all pods share the same counter)

Response when rate limit is exceeded:
8. 429 Too Many Requests with Retry-After header (seconds until the bucket refills)
9. X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset response headers on every request
10. A @WebMvcTest that verifies:
    - The 429 response is returned after the limit is exceeded
    - The Retry-After header is present and correct
    - The rate limit resets after the configured window

Prompt 10: Full Microservice Design Review

When to use: Before a production launch, a team handoff, or an architecture review board presentation, you want a comprehensive assessment of a microservice’s design covering resilience, observability, security, scalability, and operational concerns — with a prioritised remediation list.

Perform a comprehensive microservice design review for the following service.

Provide these artefacts:
1. Service description and role in the system:
[DESCRIBE THE SERVICE]

2. application.yml (complete):
[PASTE]

3. Key service and controller classes:
[PASTE]

4. Kafka producer/consumer configuration (if applicable):
[PASTE]

5. Kubernetes Deployment YAML:
[PASTE]

6. OpenAPI spec or list of endpoints:
[PASTE]

Review dimensions — evaluate every one:

RESILIENCE:
[ ] Circuit breakers on ALL downstream HTTP calls?
[ ] Timeout configured on ALL outbound HTTP/database calls?
[ ] Retry logic with exponential backoff (NOT fixed interval)?
[ ] Dead Letter Topic for all Kafka consumers?
[ ] Graceful degradation when optional dependencies are unavailable?

OBSERVABILITY:
[ ] Distributed tracing configured (Micrometer Tracing)?
[ ] traceId in all log lines?
[ ] Health probes correctly separating liveness vs readiness?
[ ] Business metrics exported (order count, payment success rate, etc.)?
[ ] Structured JSON logging (not plain text)?

SECURITY:
[ ] Service-to-service authentication (not just user-level auth)?
[ ] Secrets loaded from environment variables / Vault (not hardcoded in application.yml)?
[ ] Rate limiting on public endpoints?
[ ] Input validation on all request bodies?
[ ] HTTPS enforced (or mutual TLS for internal communication)?

SCALABILITY:
[ ] Stateless design (no in-memory session state that prevents horizontal scaling)?
[ ] Kafka consumer group configured with concurrency = partition count?
[ ] HikariCP pool sized correctly for the pod count and DB limit?
[ ] Idempotent endpoints for all mutating operations?

OPERABILITY:
[ ] Graceful shutdown configured (in-flight requests complete before pod termination)?
[ ] Rolling deploy safe (no breaking schema changes without backward compatibility)?
[ ] Feature flags for risky changes?

For each finding: severity, component, description, fix, and estimated effort in hours.

Tips for Microservice Design Prompts

  • Design contracts before code. Start with Prompt 1 (OpenAPI) for every new service. A well-specified contract prevents the most common microservice integration failures — mismatched field names, undocumented error codes, and versioning misunderstandings — before a single line of implementation code is written.
  • The Saga pattern is complex — start simple. Prompt 7 generates a choreography-based saga. If your team is new to sagas, consider starting with an orchestration-based saga (a central Saga Orchestrator service) instead — it is easier to reason about and debug. Mention “use orchestration-based saga with a SagaOrchestrator class” in the prompt to get that variant.
  • Specify your Kafka delivery guarantee explicitly. At-least-once delivery (the default) means consumers must be idempotent. Prompt 3 generates idempotency handling for consumers. Exactly-once semantics (Kafka transactions + idempotent producer) adds significant complexity and latency — only use it when duplicate processing is genuinely unacceptable and cannot be handled by consumer idempotency.

Frequently Asked Questions (FAQs)

Q1: Should I use choreography or orchestration for sagas?

Choreography (Prompt 7) is simpler to implement but harder to observe — when a saga fails, you must reconstruct the sequence from event logs across multiple services. Orchestration centralises the saga logic in one place (the orchestrator) and makes the state machine explicit, but adds another service to deploy and operate. Use choreography for simple, linear sagas (3–4 steps with rare failures). Use orchestration when the saga has conditional branches, compensating transactions that themselves need retries, or when observability of the saga state is a first-class requirement.

Q2: Is Micrometer Tracing compatible with older Spring Cloud Sleuth setups?

No — they are mutually exclusive. Spring Cloud Sleuth 3.x (for Spring Boot 2.x) and Micrometer Tracing (for Spring Boot 3.x) both provide distributed tracing but use completely different APIs and autoconfiguration. If you are migrating from Spring Boot 2.x to 3.x, remove the spring-cloud-starter-sleuth dependency entirely and replace it with micrometer-tracing-bridge-otel or micrometer-tracing-bridge-brave. The traceId and spanId MDC keys work identically in both systems, so your log patterns do not need to change.

Q3: Can I use these patterns with reactive (WebFlux) services?

Yes, with modifications. Add “reactive / WebFlux (not MVC)” to the prompt and the AI will use WebClient instead of RestTemplate, ReactiveCircuitBreaker from Resilience4j, ReactiveRedisTemplate for idempotency storage, and ReactiveHealthIndicator for Actuator. The core patterns (circuit breaker, saga, distributed tracing) are identical in design; only the API classes change.

Q4: At what scale should I introduce microservices?

The patterns in this post are worth introducing when you have independent scaling requirements (payment processing needs more capacity than reporting), when different parts of the system need independent deployment cadences, or when team boundaries make a monolith’s shared codebase a coordination bottleneck. For teams smaller than 8–10 engineers, a modular monolith with clean internal boundaries gives most of the organisational benefits of microservices at a fraction of the operational complexity. Extract services when the modular monolith boundaries become genuinely painful — not preemptively.

See Also

Conclusion

These 10 prompts address the most critical cross-cutting concerns in Java microservices: API contract design, circuit breaking, Kafka event streaming, distributed tracing, Kubernetes health probes, idempotency, saga-based consistency, service-to-service security, rate limiting, and full design reviews. Use them at the right stage: Prompt 1 before writing any implementation code, Prompts 2–9 when implementing specific patterns, and Prompt 10 before a production launch or architecture review. The AI handles the library API details and configuration syntax — your job is to provide the business context and review the output against your specific failure scenarios and operational constraints.

No Comments yet!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.