Skip to content

Discover Dapr: What Is Dapr? A new way to increase developer productivity!

January 8, 2021

You need to know about Dapr when you are developing distributed systems and cloud software since it will likely make your job much easier and more productive.  The term “Dapr” is an acronym for Distributed Application Runtime.  It is a new open source project, approaching its V 1.0 release. 

This article presents an overview of Dapr from an “increase software development productivity” point-of-view, i.e. reducing the amount of human time and work required to produce a given result. Dapr is rich in capabilities that have the potential to significantly increase the productivity of software developers and dev teams.  Increased productivity usually saves time and money.

The primary productivity increasing benefits Dapr provides are:

  • Reduced technical debt — Achieved via producing and using software that encapsulates areas having high rates of change, has an excellent separation of concerns, and has widespread decoupling.
  • Decreased amount of coding work required — Achieved by using a “lower code” approach by providing many commonly required prebuilt software parts, especially parts implementing lower business value commodity plumbing functionality, e.g. code connecting services together.
  • Increased developer focus on producing high value business logic — Achieved by reducing the need spend a lot of time producing commodity plumbing code and/or using manual process and tools where automated ones can be used.
  • Effective coordination of concurrent access to shared state — This notoriously difficult area in distributed systems can use the Actor Model in many situations to produce this result.

So what is Dapr? If I told you that Dapr is an intermediary you would not get the full picture, by far.  But this is a key idea to keep in mind.  We will revisit the view of “Dapr as an intermediary” later.

If I told you that Dapr, as an intermediary, functions as a decoupler in distributed systems of software services you would know a key core value Dapr provides. Decoupling the services of distributed systems from each other makes developing, extending and maintaining software much more time and cost efficient, and easier as well.  Why? Decoupling pieces of software from each other lets their internal code content and code structure vary independently of each other, significantly reducing the amount of work required for code changes when requirements change. Such decoupling is one of the best ways to reduce technical debt, and keep it low as the years go by, thus increasing productivity over the long run.

One key way Dapr produces decoupling is through its Building Blocks, each defining a conceptual interface to a capability commonly used by distributed systems.  For most Building Blocks Dapr also provides a number of prebuilt plug-in Components, each implementing all or parts of the Building Block interface for a specific instance of the Building Block concept.  Using prebuilt plug-in Components also acts to decrease the amount of coding work required. Without Dapr, how many times do developers have to write much-the-same low level plumbing code over and over to connect to and interact with each database or cloud service our code uses?  Many, many times!  With Dapr’s Building Block/Component approach the answer is zero!  The use of prebuilt plug-in Components saves significant time, freeing developers to focus on higher value work.  The list of Dapr links at the end of this article has details about Building Blocks.

If I told you that Dapr is a Swiss Army Knife utility service for distributed systems you will most likely want to discover Dapr’s many capabilities, given its role as both an intermediary and a decoupler.  The main capabilities offered by Dapr are as follows, with many implemented via Building Blocks and Components, but not all:

  • State Storage — Dapr defines a conceptual interface for a key/value pair State Store Building Block, and then provides a number of prebuilt plug-in state storage provider Components each connecting to a specific external key-value pair State Store like Redis storage or other popular key/value pair databases. The intent of the Dapr State Store is to provide low-latency storage, like a cache. For support of general purpose storage or database management systems see Resource Bindings and Triggers, below.
  • Pub/Sub — Similar to State Storage, Dapr defines a conceptual interface for a Pub/Sub Building Block, plus provides a number of prebuilt plug-in Pub/Sub Components each of which connects to an external Pub/Sub messaging service like Azure Service Bus Topics, or Redis Streams for example.
  • Secure Secret Access — The same idea as above, but applied to a variety of external Secret Stores like Key Vaults.
  • Resource Bindings and Triggers — The same idea as above, but applied to a variety of external resources (many are cloud resources) like queues, event hubs, service meshes, blob storage, some databases, and more. Support of SQL databases is planned subsequent to the initial V 1.0 release.
  • Service-to-Service Invocation — This Building Block allows “Daprized” services to communicate with each other via RPC with service-name-plus-method-name addressing, rather than by HTTP or gRPC addresses.  This decouples service-to-service communications from specific network endpoints.  It is required when using cluster computing hosts, and timesaving with other hosts as well.
  • Actors — This Building Block allows each “Daprized” service to use the Actor Model to take advantage of its unique characteristics of 1) keeping state and the code that manipulates the state within the same entity and 2) “turn based concurrency” that prevents state from getting out of sync when multiple clients concurrently use the same Actor.
  • Observability — The Observability Building Block conceptual interface provides tracing, metrics, and health monitoring of the flow of service-to-service interactions (including details of various Components) in a distributed system, plus sending data to external aggregators like Azure Monitor, Application Insights, and Zipkin for example.
  • Effective Security — Provides high levels of often configurable security across the breadth and depth of a “Daprized” service, and also throughout a system of collaborating “Daprized” services.
  • Middleware Pipelines — Allows custom “middleware pipeline component” code to be declaratively “plugged-in” to a Dapr request/response processing pipeline.  This allows Dapr to orchestrate developer defined custom processing of the communications between a service and Dapr, and vice versa.  For example Dapr provides a ready-to-use OAuth 2.0 middleware pipeline component.
  • Massive extensibility — This is due to Dapr’s decoupling, interface based design, and it’s componentized plug-in architecture.  Note that within a given Building Block developers may write their own code to implement a Dapr Component customized for their particular needs.
  • HTTP and gRPC Communication, plus support of most popular programming languages and cloud providers

Please note that all the above prebuilt plug-in Components are also configurable.  And the act of “plugging-in” a particular Component is simply providing a declarative configuration file in a standard Components directory. Dapr takes care of the work required to load the Component’s code and “hook-it-up”.

If I told you that Dapr is a Sidecar you would know that typically a single instance of Dapr is paired with a single instance of a service, with each running in its own process.  Dapr is currently not a code library.  A Dapr Sidecar instance and the service instance that uses it communicate with each other across their process boundaries via HTTP or gRPC (using HTTP2) as shown below in Figure 1.  When you pair an instance of a service with a Dapr Sidecar you essentially “Daprize” your service, a term used throughout this article. 

Further, each Dapr Sidecar instance is aware of all the other Dapr Sidecar instances in a system of collaborating “Daprized” services.  All these collaborating Dapr Sidecar instances communicate with each other completely behind the scenes on a separate Sidecar-only communication channel using gRPC, as shown below in Figure 1.  Communication between Dapr Sidecars this way is key to Dapr’s Pub/Sub, Service Invocation and Actor Model capabilities.    A Dapr Sidecar and the service that uses a Dapr Sidecar instance are typically run in separate containers or as separate stand-alone processes.

Figure 1 — Typical arrangement of “Daprized” Services and their Dapr Sidecars.

A “Daprized” service usually only interacts with its single, private Dapr Sidecar, as shown above in Figure 1, leaving all the messy plumbing details and knowledge of how to communicate with other services, storage, secrets, etc. to the Dapr Sidecars themselves, plus the Dapr Components used within the Dapr Sidecar instances.  This makes the service code much less complicated and provides a great separation of concerns between the business logic code in the service and the plumbing logic code (aka infrastructure code) in the Dapr Sidecar and its Components.  In Figure 1 above, the yellow services contain all the business logic, while the pink Dapr Sidecars contain most, if not all, of the plumbing code. This separation of concerns between business logic code and plumbing logic code is one key to the significant reduction in technical debt resulting from the use of Dapr.   Thus, when requirements inevitably change usually much less code has to be changed than is typically the case when plumbing code is intermixed and intertwined with business logic code

Finally, having a strong separation of concerns between business logic and plumbing code, coupled with Components, also focuses more developer time on the high value business logic, and less time on low value commodity plumbing code. While low level plumbing code is absolutely necessary, developing the low level plumbing code is complex, time consuming, and requires a high level of experience — all of which cost time and money.  Using prebuilt “plug-in” components instead allows much of that developer time and skill to be redirected into developing the business logic that produces the value most directly relevant to the software’s end users.

Looking again at Dapr as an intermediary, one can now see how a Dapr Sidecar (plus the Components it uses) stands between the service that uses the Sidecar and all the other services in a distributed system, plus all the possible cloud services or on-prem services that a “Daprized” service can connect to.  That can be a lot of services!  Thus, Dapr’s role as an intermediary is vital when understanding the 3 following main usage scenarios for “Daperized” services.

  • Portable services — Write once/Run anywhere.  Dapr excels in this scenario, allowing developers to simply plug in different Components (configured declaratively) that the service uses to interact with external services and resources.  Putting a service in a container, along with its Dapr Sidecar instance in a separate container, provides a very high degree of isolation from hard coded external dependencies.  This allows the same “Daprized” and containerized service to run on-prem, in the cloud, or on Edge devices (like an IoT field gateway) without having to change the service code.  Rather, changes may only be required to the declarative definitions of the Dapr Components interfacing to external dependencies.  Essentially integrating a containerized Dapr Sidecar with a containerized service virtually decouples all external dependencies of the service, allowing maximum portability with a low cost of work required to do a port to a different hosting environment or to connect with different external services.
  • Polygot systems of services.  With Dapr’s Service Invocation, Pub/Sub, Secrets, plus State Storage and Resource Bindings and Triggers, services written in a wide variety of languages can communicate with each other without having to rewrite a lot of code and without developers having to learn a bunch of other languages.  To facilitate this Dapr supplies Software Development Kits (SDKs) for many popular languages like .NET C#, Java, JavaScript, Python, and Go to mention a few. Essentially developers using any supported language and SDK will program against the same standardized Dapr interfaces rather than a bunch of ad hoc language specific or external service interfaces.  This is also facilitates the other 2 usage scenarios as well.
    • Extending the life of legacy software also falls under this usage scenario.  Note, however, that the legacy software absolutely must support HTTP interactions with its Dapr Sidecar.  If that is the case, then it may be feasible to “Daprize” the legacy software to allow it to more cost effectively be part of a system of services, communicating with other services and resources via a Dapr Sidecar and its Building Blocks and Components.
  • Static services with dynamic dependencies.  Need to change your Pub/Sub messaging backbone from say Redis to Azure Service Bus?  This often happens when organizations need to adapt to change.  With a “Daprized” system of services the per service cost of making this change (i.e. changing the declarative Component definitions) may be quite small compared to the cost of rewriting many lines of code that implements Pub/Sub messaging across many individual services without using Dapr.  The same applies to the other Building Blocks and their Components.

Also note that “Daprized” services can be hosted in containers on Kubernetes or on other hosts that support containers like Docker, including using Docker Compose where appropriate.  “Daprized” services can also be hosted without using containers as standalone processes on a variety of compute hosts, including your own development system.

Looking at the history of software, the potential time and labor saving characteristics of Dapr is really a big deal!  There has not yet been anything quite like Dapr so far, that can run almost anywhere and also offers massive decoupling to the services of distributed systems, plus componentization and an excellent separation of concerns.  All these decrease the work required in initial development and also result in significantly lower technical debit than usual in the long run.  It all adds up to potentially significant increases in software development productivity in the short and long run, reducing the amount of work needing to be done, saving time and money.

If I told you that Dapr will be the glue that holds together the distributed systems of the near future, would you believe me?   Time will tell.  I hope this blog spurs you to investigate Dapr to see what it can do for you. 

Again, what is Dapr? Dapr is an open source project initially sponsored by Microsoft.  As of the date of writing this blog the Dapr development team has just released their second Release Candidate, RC 2.  This means that the first stable release of Dapr, version 1.0, can be expected in the first quarter of 2021. 

Above I have glossed over many key details, so please read the following links that provide in depth information.  Plus, the Dapr open source team is very open to questions, concerns, bug reports, and feature requests, and is available at some of the links below.

I hope you find the above links as useful as I have, and thanks for taking the time to read this blog. 

George Stevens

Software Architect, Sr. Software Engineer for Solid Value Software, LLC. 

Microsoft Certified Azure Developer

P.S. In December 2019, after hearing good things about Dapr, I started regularly attending the hour long Dapr Community Meetings every two weeks in order to ascertain whether Dapr actually had the potential it seemed that it could have. Then from mid-November 2020 through the end of December 2020 I averaged about 30 hours per week learning to use the basics of Dapr (via the Dapr .NET SDK) by doing  exploratory coding to develop a system of  4 collaborating ASP.NET Core gRPC microservices.  This includes writing C# .NET code to use many of the above listed capabilities, coming up to speed on the basics of gRPC as implemented in ASP.NET Core, and doing in depth reading and study of the Dapr documentation and some code examples.  My goal was to be able to assess whether Dapr is a highly useful technology that I can recommend.  While I still have a few areas to explore in the very near future, my assessment of Dapr is highly favorable as this article indicates.  However, as with all distributed systems development, allow sufficient time to learn to use the underlying technologies before making firm software delivery time commitments.

“Discover Dapr: What Is Dapr? A new way to increase developer productivity!” by George Stevens is licensed under Attribution 4.0 International

Leave a comment

Design a site like this with WordPress.com
Get started