Dapr Reference: Service Invocation, Pub/Sub & State Management for Distributed Apps
Dapr patterns for distributed microservices on Kubernetes.
The core idea: stop implementing distributed systems primitives yourself
# Without Dapr: you implement retry logic, service discovery, circuit breaker, mTLS
response = requests.get(f"http://user-service.production.svc.cluster.local/users/{user_id}",
timeout=10, ...) # manual retry/timeout
# With Dapr: plain HTTP to localhost — Dapr handles the rest
response = requests.get(f"http://localhost:3500/v1.0/invoke/user-service/method/users/{user_id}")
# Dapr handles: service discovery, mTLS, retries, distributed tracing
Swap brokers without changing app code
# Dev: Redis (local)
spec:
type: pubsub.redis
# Prod: Kafka (change one line, zero app code changes)
spec:
type: pubsub.kafka
metadata:
- name: brokers
value: kafka:9092
Your publisher/subscriber code is identical — it always calls Dapr's HTTP API. The broker is a config concern, not a code concern.
Pub/Sub in practice (publish + subscribe)
# Publish:
curl -X POST http://localhost:3500/v1.0/publish/pubsub/orders -d '{"orderId": "123"}'
# Your app receives it on a route Dapr calls:
@app.route("/orders", methods=["POST"])
def handle_order():
return json.dumps({"status": "SUCCESS"}), 200
State management with optimistic concurrency
# Get (ETag returned in header):
curl http://localhost:3500/v1.0/state/statestore/cart-123
# Update only if not changed since last read:
curl -X PUT http://localhost:3500/v1.0/state/statestore/cart-123 -H "If-Match: your-etag" \ # fails with 409 if someone else updated it
-d '{"items": [...]}'
Full reference (building blocks table, service resiliency config with circuit breaker, Subscription CRD, state transactions for atomic multi-key updates, secret scope restrictions, local dev with dapr run --components-path, dashboard): releaserun.com/dapr-reference