Skip to content

feat: Dapr Service Invocation for Secure Inter-Service Communication #34

Description

@mjunaidca

Summary

Replace direct HTTP calls between services with Dapr Service Invocation for automatic mTLS, retries, service discovery, and observability.

Current State

  • Services call each other via direct HTTP (e.g., httpx.post("http://notification-service:8001/..."))
  • No automatic retries on transient failures
  • No mTLS between services
  • Service URLs hardcoded or in config
  • No distributed tracing propagation

Proposed Architecture

┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────────┐
│ API Service │────►│ Dapr        │────►│ Dapr        │────►│ Notification    │
│             │     │ Sidecar     │     │ Sidecar     │     │ Service         │
│             │     │ (mTLS)      │     │ (mTLS)      │     │                 │
└─────────────┘     └─────────────┘     └─────────────┘     └─────────────────┘

# Instead of:
await httpx.post("http://notification-service:8001/notify", json=data)

# Use Dapr Service Invocation:
await dapr_client.invoke_method("notification-service", "notify", data)

Benefits

Feature Direct HTTP Dapr Invocation
mTLS Manual setup Automatic ✅
Retries Manual implementation Built-in ✅
Service Discovery Hardcoded URLs Automatic ✅
Load Balancing External LB needed Built-in ✅
Tracing Manual propagation Automatic ✅
Circuit Breaker Manual implementation Configurable ✅

Implementation Steps

  • Configure Dapr app-id for each service
  • Create dapr_invoke.py utility module
  • Replace API → Notification Service calls
  • Replace API → SSO validation calls (if any)
  • Add retry policies in Dapr config
  • Enable distributed tracing (Zipkin/Jaeger)
  • Add circuit breaker configuration
  • Update Helm charts with Dapr annotations

Acceptance Criteria

  • All inter-service calls use Dapr invocation
  • Automatic retry on 5xx errors (configurable)
  • mTLS enabled between all services
  • Traces visible in observability tool
  • Services discoverable by app-id (no hardcoded URLs)
  • Graceful degradation if target service unavailable

Technical Notes

# Dapr Service Invocation example
from dapr.clients import DaprClient

async with DaprClient() as client:
    # Invoke method on another service
    response = await client.invoke_method(
        app_id="notification-service",
        method_name="notify",
        data=json.dumps(payload),
        content_type="application/json",
    )
# Dapr retry policy (resiliency.yaml)
apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
  name: service-resiliency
spec:
  policies:
    retries:
      default:
        policy: constant
        maxRetries: 3
        duration: 1s

Labels

enhancement learning dapr security observability phase-v2


📚 Learning Goal: Dapr Service Invocation Building Block + Resiliency Patterns

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions