It is remarkable to see the transformation over the last few years as more and more developers build scalable, cloud native applications, taking advantage of managed services to deploy and run them. With this transformation, microservice architectures have become the standard for building cloud native applications, and it is predicted that by 2022, 90% of new apps will feature microservice architectures. A microservice architecture offers compelling benefits, including scalability, loose service coupling and independent deployments. However, this approach can come at a high cost of understanding and skilling on distributed systems.
Developers want to focus on business logic, frequently and incrementally migrating legacy code, while leaning on the platforms to provide their applications with the required scale, resiliency, maintainability, elasticity and the other attributes of cloud-native architectures. What developers find though, is limited portability between cloud and edge and they continually end up solving the same distributed system problems such as state management, resilient method calling and handling events. In addition, many programming runtimes often have narrow language support and tightly controlled feature sets, making it challenging to build microservice architectures.
Building event driven, stateless, and stateful applications
For example, when building an e-commerce application consisting of several services, you may want to use a stateful actor to represent the cart service and call stateless functions for the payment and shipping services. Writing this application may involve working with multiple languages, developer frameworks and infrastructure platforms, as well as integrating with external services. Understanding and managing such a complex technical stack distracts developers from building business value.
To enable all developers using any language and any framework to easily build portable microservices applications, whether writing new code or migrating existing code, we are excited to announce Announcing Distributed Application Runtime (Dapr).
Dapr: Microservice building blocks for cloud and edge
Dapr is an open source, portable, event-driven runtime that makes it easy for developers to build resilient, microservice stateless and stateful applications that run on the cloud and edge. Dapr embraces the diversity of all programming languages and developer frameworks and simplifies building applications such as the e-commerce example.
Dapr consists of a set of building blocks accessed by standard HTTP or gRPC APIs that can be called from any programming language. These building blocks empower all developers with proven, industry best practices and each building block is independent; you can use one, some, or all of them in your applications. In addition, through the open source project, we welcome the community to add new building blocks and contribute new components into existing ones. Dapr is completely platform agnostic, meaning you can run your applications locally, on any Kubernetes cluster, and other hosting environments that Dapr integrates with. This enables developers to build microservice applications that can run on both the cloud and edge with no code changes.
Build applications with any language and any framework by calling Dapr building blocks over standard APIs
Dapr building blocks in this alpha release
There are many capabilities needed when architecting and building microservices applications. In this first open source alpha release of Dapr, we focused on providing some of the most frequently used building blocks.
- Service Invocation – Resilient service-to-service invocation enables method calls, including retries, on remote services wherever they are running in the supported hosting environment.
- State management – With state management for key/value pairs, long running, highly available, stateful services can be easily written, alongside stateless services in the same application. The state store is pluggable and can include Azure Cosmos or Redis, with others such as AWS DynamoDB on the component roadmap.
- Publish and subscribe messaging between services – Publishing events and subscribing to topics between services enables event-driven architectures to simplify horizontal scalability and make them resilient to failure.
- Event driven resource bindings – Resource bindings and triggers build further on event-driven architectures for scale and resiliency by receiving and sending events to and from any external resources such as databases, queues, file systems, blob stores, webhooks, etc. For example, your code can be triggered by a message on an Azure EventHub service and write data to Azure CosmosDB.
- Virtual actors – A pattern for stateless and stateful objects that make concurrency simple with method and state encapsulation. Dapr provides many capabilities in its virtual actor runtime including concurrency, state, life-cycle management for actor activation/deactivation and timers and reminders to wake up actors.
- Distributed tracing between services – Easily diagnose and observe inter-service calls in production using the W3C Trace Context standard and push events to tracing and monitoring systems.
Standard APIs for portability and extensibility
So how do you use these Dapr building blocks? Say for example, that you are using the Azure Functions runtime in a microservice application that you have deployed into a Kubernetes cluster and you would like to take advantage of using the pub/sub pattern to send messages between the services. Today, the Azure Functions runtime does not have this capability built in, however by using the Dapr pub/sub building block over http, you can easily add this new capability. You have new developer powers!
Furthermore, the Dapr pub/sub building block has a pluggable component model, meaning that you can dynamically choose different implementations for how the messages are sent, without changing any code. For example, you can choose the Redis, Kafka, or Azure Service Bus pub/sub Dapr component depending on your preferences. And in both cases the code remains the same, including being portable across different supported infrastructures, by using a standard API.
To enable both portability and ease of integration with existing code, Dapr provides standard APIs over http or gRPC. Staying with the pub/sub example, the node code below shows how to subscribe to topics called ‘A’ and ‘B’ with the “http://<myappaddress>/dapr/subscribe” endpoint and then have your application be notified when messages are published to these topics.
For comparison, here is the same code written in C# using a UseStartup() handler called from ASP.NET Core CreateWebHostBuilder().
Publishing an event to services subscribed to these topics is as simple as calling the Dapr local http publish API with the name of the topic and payload. The example node code below shows how to use the Dapr publish API (on local port 3500), which can also be done using a curl command:
As these examples show, using Dapr in your services does not require taking compile time dependencies, just simply how to craft a URL with a message body.
Sidecar architecture and supported infrastructures
Dapr exposes its APIs as a sidecar architecture, either as a container or as a process, not requiring the application code to include any Dapr runtime code. This makes integration with Dapr easy from other runtimes, as well as providing separation of the application logic for improved supportability.
Dapr running as a side-car process
In container hosting environments such a Kubernetes, Dapr runs as a side-car container with the application container in the same pod.
Dapr running as a side-car container in a Kubernetes pod
Dapr has a CLI to make getting started easy and include support for running locally on developer machines, any Kubernetes cluster (including minikube), with other infrastructure platforms such as IoT Edge, and Service Fabric on the roadmap. To get started with Dapr, simply run:
dapr init (for local deployment)
dapr init --kubernetes (for Kubernetes deployment)
Developer language SDKs and frameworks
Furthermore, Dapr can also be integrated with any developer framework. For example, in the Dapr .NET SDK you will find ASP.NET Core integration, which brings stateful routing controllers that can respond to pub/sub events from other services, making ASP.NET Core an even better framework for building microservice web applications.
Learn more and contribute
We have several partners including Willow and Geek+ building solutions in the cloud and on edge devices that you will hear more about at the upcoming Ignite conference. This initial release of the Dapr runtime and SDKs is just the early start, our goal is to bring Dapr to a vendor-neutral foundation to enable open governance and collaboration. This is a journey and we need your help and input, whether this is writing new binding components to integrate with resources, suggesting new building blocks or creating an SDK for your favorite language (Cobol anyone?). We want to hear from you.
It’s a tremendous time to be a developer in the era of microservice development, and we are excited to see where you will take this project, what you build with it, and how it evolves.