Implementing Service-to-Service Communication

1. Implementing REST Client Logic

Example: Spring RestClient (modern)

RestClient client = RestClient.builder()
    .baseUrl("https://payments.internal")
    .defaultHeader("Authorization", "Bearer " + token)
    .requestFactory(new HttpComponentsClientHttpRequestFactory())
    .build();

Receipt r = client.post()
    .uri("/charges")
    .contentType(MediaType.APPLICATION_JSON)
    .body(new ChargeRequest(...))
    .retrieve()
    .body(Receipt.class);

2. Implementing gRPC Client/Server

Example: Server stub

public class OrderServiceImpl extends OrderServiceGrpc.OrderServiceImplBase {
    public void place(PlaceOrderRequest req, StreamObserver<OrderResponse> obs) {
        var o = service.place(toDomain(req));
        obs.onNext(toProto(o));
        obs.onCompleted();
    }
}

3. Implementing Service Discovery Logic

ApproachDetail
DNSKubernetes service DNS
RegistryEureka, Consul, etcd
Service meshIstio, Linkerd
Client-side LBSpring Cloud LoadBalancer

4. Implementing Load Balancing Logic

AlgorithmUse
Round-robinDefault, equal capacity
Least connectionsLong-lived requests
WeightedHeterogeneous nodes
Consistent hashingSticky sessions, cache affinity
EWMA / latency-basedAdaptive

5. Implementing Circuit Breaker for External Calls

Example: Resilience4j

@CircuitBreaker(name = "fx", fallbackMethod = "stale")
@Retry(name = "fx")
@TimeLimiter(name = "fx")
public CompletableFuture<Rate> getRate(String pair) {
    return CompletableFuture.supplyAsync(() -> client.fetch(pair));
}
public CompletableFuture<Rate> stale(String pair, Throwable t) {
    return CompletableFuture.completedFuture(cache.get(pair));
}

6. Implementing Retry Logic for Service Calls

SettingDetail
Retryable codes5xx, 429, network
Non-retryable4xx (except 429)
BackoffExponential + jitter
Honor Retry-AfterServer hint takes priority
IdempotencyRequired for non-GET

7. Implementing Service Mesh Patterns

CapabilityDetail
mTLSAuto cert mgmt + rotation
Traffic shapingCanary, A/B, mirror
Retries / timeoutsMesh-level policy
ObservabilityMetrics, traces, logs out-of-the-box
AuthZService identity policies

8. Implementing API Gateway Communication

ConcernDetail
RoutingPath/host → upstream
AuthJWT validation, API key
Rate limitPer consumer
AggregationBFF pattern
ToolsSpring Cloud Gateway, Kong, Envoy

9. Implementing Saga Pattern

[Order] ──> [Reserve Inventory] ──> [Charge Payment] ──> [Ship]
   ↑                ↓ failure              ↓ failure         ↓ failure
   └── compensate: Release ←── compensate: Refund ←── compensate: Cancel
  
StyleDetail
ChoreographyEach service reacts to events
OrchestrationCentral coordinator (e.g., Camunda)
CompensationDefine for every step

10. Implementing Event-Driven Communication

PatternDetail
Pub/subLoose coupling, fan-out
OutboxAtomicity with DB write
Event sourcingEvents as truth
CDCDebezium streams DB changes

11. Implementing Synchronous vs Asynchronous

Sync (REST/gRPC)

  • Immediate response
  • Simple to reason about
  • Tight coupling on availability
  • Cascade failures possible

Async (Queue/Event)

  • Decoupled, resilient
  • Buffering absorbs spikes
  • Eventual consistency
  • Harder debugging

12. Implementing Service Versioning

ApproachDetail
URI version/v2/orders
Header versionAPI-Version: 2
Side-by-sideRun v1 + v2 during migration
Deprecation policySunset header, advance notice
Backward compatAdditive changes only within version