Pular para o conteúdo

Dapr Cheat Sheet

Overview

Dapr (Distributed Application Runtime) is a portable, event-driven runtime that simplifies building resilient, microservice-based applications. It runs as a sidecar process alongside your application and provides building blocks for common distributed system patterns including service invocation, state management, pub/sub messaging, bindings, actors, and observability.

Dapr is language-agnostic and communicates with applications via HTTP or gRPC APIs. It abstracts away infrastructure concerns by providing pluggable components — you can switch between Redis, PostgreSQL, Kafka, Azure Service Bus, and many other backends without changing application code. Dapr runs on Kubernetes, self-hosted environments, and edge devices.

Installation

Dapr CLI

# macOS
brew install dapr/tap/dapr-cli

# Linux
wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash

# Windows (PowerShell)
# powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"

# Verify
dapr --version

Initialize Dapr

# Self-hosted mode (Docker containers for Redis, Zipkin, Placement)
dapr init

# Kubernetes mode
dapr init -k

# Slim init (no Docker dependencies)
dapr init --slim

# Check status
dapr status -k    # Kubernetes
dapr dashboard    # Open web dashboard

Building Blocks

BlockDescriptionAPI Endpoint
Service InvocationCall other services/v1.0/invoke/{appId}/method/{method}
State ManagementKey-value state store/v1.0/state/{storeName}
Pub/SubPublish and subscribe/v1.0/publish/{pubsubName}/{topic}
BindingsExternal system triggers/v1.0/bindings/{bindingName}
ActorsVirtual actor pattern/v1.0/actors/{actorType}/{actorId}
SecretsSecret store access/v1.0/secrets/{storeName}/{key}
ConfigurationDynamic config/v1.0/configuration/{storeName}
Distributed LockMutual exclusion/v1.0-alpha1/lock/{storeName}
WorkflowsDurable workflows/v1.0-beta1/workflows

Running Applications

# Run an app with Dapr sidecar
dapr run --app-id myapp --app-port 3000 -- node app.js

# Run with specific config
dapr run --app-id myapp \
  --app-port 3000 \
  --dapr-http-port 3500 \
  --dapr-grpc-port 50001 \
  --components-path ./components \
  --config ./config.yaml \
  -- python app.py

# Run without an app (for testing)
dapr run --app-id myapp --dapr-http-port 3500

# List running apps
dapr list

# Stop an app
dapr stop myapp

# View logs
dapr logs --app-id myapp -k

Service Invocation

# Invoke a method on another service
curl http://localhost:3500/v1.0/invoke/order-service/method/orders \
  -H "Content-Type: application/json" \
  -d '{"orderId": "123"}'

# Invoke with POST
curl -X POST http://localhost:3500/v1.0/invoke/payment-service/method/pay \
  -H "Content-Type: application/json" \
  -d '{"amount": 99.99}'
# Python SDK
from dapr.clients import DaprClient

with DaprClient() as client:
    response = client.invoke_method(
        app_id='order-service',
        method_name='orders',
        data=json.dumps({'orderId': '123'}),
        http_verb='GET',
    )
    print(response.text())

State Management

# Save state
curl -X POST http://localhost:3500/v1.0/state/statestore \
  -H "Content-Type: application/json" \
  -d '[{"key": "order-123", "value": {"status": "pending", "total": 99.99}}]'

# Get state
curl http://localhost:3500/v1.0/state/statestore/order-123

# Delete state
curl -X DELETE http://localhost:3500/v1.0/state/statestore/order-123

# Bulk get
curl -X POST http://localhost:3500/v1.0/state/statestore/bulk \
  -H "Content-Type: application/json" \
  -d '{"keys": ["order-123", "order-456"]}'

# Transaction
curl -X POST http://localhost:3500/v1.0/state/statestore/transaction \
  -H "Content-Type: application/json" \
  -d '{
    "operations": [
      {"operation": "upsert", "request": {"key": "k1", "value": "v1"}},
      {"operation": "delete", "request": {"key": "k2"}}
    ]
  }'

Pub/Sub Messaging

# Publish a message
curl -X POST http://localhost:3500/v1.0/publish/pubsub/orders \
  -H "Content-Type: application/json" \
  -d '{"orderId": "123", "status": "created"}'
# Subscribe (Python SDK)
from dapr.ext.grpc import App
import json

app = App()

@app.subscribe(pubsub_name='pubsub', topic='orders')
def order_handler(event):
    data = json.loads(event.Data())
    print(f"Received order: {data['orderId']}")

app.run(50051)

Subscription Configuration

# subscription.yaml
apiVersion: dapr.io/v1alpha1
kind: Subscription
metadata:
  name: order-subscription
spec:
  pubsubname: pubsub
  topic: orders
  route: /orders
  deadLetterTopic: orders-dead

Component Configuration

State Store (Redis)

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  version: v1
  metadata:
    - name: redisHost
      value: localhost:6379
    - name: redisPassword
      value: ""
    - name: actorStateStore
      value: "true"

Pub/Sub (Redis)

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: pubsub
spec:
  type: pubsub.redis
  version: v1
  metadata:
    - name: redisHost
      value: localhost:6379
    - name: redisPassword
      value: ""

Pub/Sub (Kafka)

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: kafka-pubsub
spec:
  type: pubsub.kafka
  version: v1
  metadata:
    - name: brokers
      value: "kafka:9092"
    - name: consumerGroup
      value: "mygroup"
    - name: authType
      value: "none"

Secret Store

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: secrets
spec:
  type: secretstores.kubernetes
  version: v1

Kubernetes Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "order-service"
        dapr.io/app-port: "3000"
        dapr.io/log-level: "info"
        dapr.io/sidecar-cpu-request: "100m"
        dapr.io/sidecar-memory-request: "64Mi"
        dapr.io/config: "appconfig"
    spec:
      containers:
        - name: order-service
          image: myregistry/order-service:v1
          ports:
            - containerPort: 3000

Advanced Usage

Resiliency Policies

apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
  name: myresiliency
spec:
  policies:
    retries:
      retryForever:
        policy: constant
        duration: 5s
        maxRetries: -1
      retry3Times:
        policy: exponential
        maxInterval: 15s
        maxRetries: 3
    circuitBreakers:
      simpleCB:
        maxRequests: 1
        interval: 30s
        timeout: 60s
        trip: consecutiveFailures >= 5
    timeouts:
      general: 5s
  targets:
    apps:
      order-service:
        retry: retry3Times
        circuitBreaker: simpleCB
        timeout: general
    components:
      statestore:
        outbound:
          retry: retryForever

Workflows

import dapr.ext.workflow as wf

wf_runtime = wf.WorkflowRuntime()

@wf_runtime.workflow(name='order_workflow')
def order_workflow(ctx: wf.DaprWorkflowContext, order: dict):
    result = yield ctx.call_activity(validate_order, input=order)
    if result['valid']:
        yield ctx.call_activity(process_payment, input=order)
        yield ctx.call_activity(ship_order, input=order)
    return result

@wf_runtime.activity(name='validate_order')
def validate_order(ctx, order: dict):
    return {'valid': order.get('amount', 0) > 0}

CLI Commands

CommandDescription
dapr initInitialize Dapr
dapr run --app-id <id> -- <cmd>Run app with sidecar
dapr listList running applications
dapr stop <app-id>Stop an application
dapr dashboardOpen web dashboard
dapr components -kList components (K8s)
dapr configurations -kList configs (K8s)
dapr status -kCheck Dapr system status
dapr upgrade -kUpgrade Dapr on K8s
dapr uninstall -kUninstall from K8s

Troubleshooting

IssueSolution
Sidecar not injectingVerify dapr.io/enabled: "true" annotation; check Dapr operator logs
State store errorsVerify component config; check Redis/DB connectivity
Pub/sub messages lostCheck subscription route matches app endpoint; verify component config
Service invocation 404Verify target app-id matches; ensure target app is running
High latencyCheck sidecar resource limits; tune component connection pools
Component not loadingVerify component YAML in components directory; check naming
Actor placement issuesEnsure placement service is running; check actor state store config
mTLS errorsVerify Sentry service is healthy; check certificate expiration