DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

How does AI transform chaos engineering from an experiment into a critical capability? Learn how to effectively operationalize the chaos.

Data quality isn't just a technical issue: It impacts an organization's compliance, operational efficiency, and customer satisfaction.

Are you a front-end or full-stack developer frustrated by front-end distractions? Learn to move forward with tooling and clear boundaries.

Developer Experience: Demand to support engineering teams has risen, and there is a shift from traditional DevOps to workflow improvements.

Related

  • Vibe Coding With GitHub Copilot: Optimizing API Performance in Fintech Microservices
  • Failure Handling Mechanisms in Microservices and Their Importance
  • Solving Interface Challenges With the BFF Pattern
  • Develop Microservices Using Azure Functions, API Management

Trending

  • Understanding the Mandelbrot Set: A Beautiful Benchmark for Computing Power
  • How You Clear Your HTML5 Canvas Matters
  • Improving Cloud Data Warehouse Performance: Overcoming Bottlenecks With AWS and Third-Party Tools
  • Integrate Spring With Open AI
  1. DZone
  2. Software Design and Architecture
  3. Microservices
  4. Orchestrating Microservices with Dapr: A Unified Approach

Orchestrating Microservices with Dapr: A Unified Approach

Explore how Dapr simplifies microservices orchestration, enabling scalable and secure microservices without infrastructure complexity.

By 
Vigneshwaran Manivelmurugan user avatar
Vigneshwaran Manivelmurugan
·
May. 20, 25 · Tutorial
Likes (0)
Comment
Save
Tweet
Share
2.9K Views

Join the DZone community and get the full member experience.

Join For Free

Introduction

Modern software architectures are increasingly embracing microservices to improve scalability, flexibility, and resilience. However, as the number of systems expands, managing inter-service communication, data persistence, event-driven messaging, and security becomes more complex. Additionally, as a product scales, organizations often inadvertently develop strong dependencies on specific database providers, messaging middleware, or cloud vendors. This tight coupling makes future changes challenging, often requiring extensive refactoring.

Dapr (Distributed Application Runtime) offers a unified abstraction for handling these concerns, allowing microservices to interact with databases, message queues, APIs, and secrets stores in a cloud-agnostic and infrastructure-independent manner.

A visual representation of Dapr allowing for the interaction between databases, message queues, APIs, and secrets, allowing for a unified abstraction.

Figure 1: How Dapr works

This article explores how Dapr simplifies microservices orchestration, using an Order Management System (OMS) as an example. We'll demonstrate:

  • Database access for state management
  • Event-driven messaging for data processing across services
  • Service-to-service invocation for inter-service communication
  • Secure secrets management for handling credentials

A diagram of how Dapr simplifies microservices orchestration by allowing for database access, event-driven messaging, service-to-service invocation, and secure secrets management.

Figure 2: How Dapr simplifies microservices orchestration


Managing State Without Tight Coupling

One of the fundamental needs in microservices is persistent storage. Instead of using a database SDK tied to a specific provider, Dapr provides a state management API that works across multiple databases such as PostgreSQL, DynamoDB, and Redis.  

Configuration

To enable database access, we configure Dapr to use AWS DynamoDB by creating a component file as seen below:

YAML
 
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: orderstatestore
  namespace: default
spec:
  type: state.aws.dynamodb
  version: v1
  metadata:
  - name: region
    value: us-east-1
  - name: table
    value: OrdersTable
  - name: partitionKey
    value: orderId


This configuration tells Dapr to use DynamoDB as the storage backend.

Saving and Retrieving Data via Dapr API  

Instead of integrating directly with AWS SDKs, our order service interacts with the database via Dapr’s state API:

Java
 
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    private static final String STATE_STORE_NAME = "orderstatestore";
    private final DaprClient daprClient;

    public OrderService() {
        this.daprClient = new DaprClientBuilder().build();
    }

    public void createOrder(Order order) {
      	//Blocking (Synchronous) Approach
        daprClient.saveState(STATE_STORE_NAME, order.getOrderId(), order).block();
    }

    public Order getOrder(String orderId) {
        return daprClient.getState(STATE_STORE_NAME, orderId, Order.class).block().getValue();
    }
}


Using Dapr’s state API, the underlying database is abstracted, enabling seamless migration. This eliminates the need for AWS-specific configurations within the application code, allowing developers to switch databases without modifying the business logic.

Pub/Sub Messaging: Event-Driven Data Processing 

Many microservices follow event-driven architectures where services communicate via message brokers. Instead of integrating directly with Kafka, RabbitMQ or AWS SNS/SQS, Dapr provides a generic pub/sub API.

Configuring

 To enable event-driven messaging, we configure Dapr to use AWS SNS as seen below:

YAML
 
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: orderspubsub
  namespace: default
spec:
  type: pubsub.aws.sns
  version: v1
  metadata:
  - name: region
    value: us-east-1
  - name: topic
    value: orderCreatedTopic


Publishing Events

Once an order is created, we publish an event to AWS SNS without directly using AWS SDKs. This enables downstream applications to trigger subsequent processes, such as shipping and billing. 

Java
 
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import org.springframework.stereotype.Service;

@Service
public class OrderEventPublisher {

    private final DaprClient daprClient;

    public OrderEventPublisher() {
        this.daprClient = new DaprClientBuilder().build();
    }

    public void publishOrderCreatedEvent(Order order) {
      	//Publish as Fan-out message for point to point use invokeMethod
        daprClient.publishEvent("orderspubsub", "orderCreatedTopic", order).block();
    }
}


Subscribing Events 

Create a Dapr subscription file (order-subscription.yaml) so that the service can listen for the order-created event:

YAML
 
apiVersion: dapr.io/v1alpha1
kind: Subscription
metadata:
  name: order-subscription
spec:
  pubsubname: orderspubsub
  topic: orderCreatedTopic
  route: /orders
scopes:
  - payment-service


The payment service listens for order events:

Java
 
import org.springframework.web.bind.annotation.*;

@RestController
public class PaymentEventListener {

    @Topic(name = "orderCreatedTopic", pubsubName = "orderspubsub")
    @PostMapping("/orders")
    public void handleOrderEvent(@RequestBody Order order) {
        System.out.println("Processing payment for Order ID: " + order.getOrderId());
      	// Implement further processing (e.g., triggering shipping)
    }
}


This decouples order and payment services, allowing them to scale independently.

Service Invocation

Instead of using hardcoded URLs like traditional REST APIs, Dapr allows microservices to communicate dynamically.

 The payment service retrieves order details via Dapr without knowing its exact hostname/IP:

Java
 
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import org.springframework.stereotype.Service;

@Service
public class PaymentService {

    private final DaprClient daprClient;

    public PaymentService() {
        this.daprClient = new DaprClientBuilder().build();
    }

    public Order getOrderDetails(String orderId) {
        return daprClient.invokeMethod("orderservice", "orders/" + orderId, null, Order.class).block();
    }
}


Services do not need to handle discovery or manage hardcoded addresses, as Dapr automatically takes care of networking.

Secrets Management

Instead of storing credentials in environment variables or application properties, Dapr provides a secrets management API, enabling secure retrieval of secrets from providers like  AWS Secrets Manager or HashiCorp Vault. 

Configuring

Below is how to configure this using Dapr:

YAML
 
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: aws-secrets
  namespace: default
spec:
  type: secretstores.aws.secretsmanager
  version: v1
  metadata:
  - name: region
    value: us-east-1


Retrieving Secrets

The order service securely retrieves credentials via Dapr’s secret store API:  

Java
 
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class SecretService {

    private final DaprClient daprClient;

    public SecretService() {
        this.daprClient = new DaprClientBuilder().build();
    }

    public Map<String, String> getDatabaseSecrets() {
        return daprClient.getSecret("aws-secrets", "dbPassword").block();
    }
}


This ensures credentials are securely stored and accessed only when needed.

Conclusion

Dapr streamlines microservice orchestration with a unified, cloud-agnostic abstraction for database access, messaging, service invocation, and secrets management. It supports polyglot architectures, enabling seamless interaction across different programming languages without infrastructure dependencies. By integrating database and messaging components, developers can build scalable, maintainable systems without vendor lock-in. With built-in features like circuit breakers, retries, and observability, Dapr enhances resilience, reduces complexity, and allows services to evolve independently. By abstracting infrastructure concerns, it enables teams to focus on business logic, accelerating development and supporting scalable, distributed systems across any cloud or hybrid environment.

API microservices

Opinions expressed by DZone contributors are their own.

Related

  • Vibe Coding With GitHub Copilot: Optimizing API Performance in Fintech Microservices
  • Failure Handling Mechanisms in Microservices and Their Importance
  • Solving Interface Challenges With the BFF Pattern
  • Develop Microservices Using Azure Functions, API Management

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • [email protected]

Let's be friends: