This is the third article in a Dapr series. The second one can be found here. If you missed it, please make sure to check it out.
This time, we are finally going to use Dapr with an actual application. The plan for this post is to create a component of Dapr element and configure it for a specific application. Once this is done, we will use it with the running application. That's it. Sounds easy? Great, because it is. Still, I’m sure we will find some elements that are useful and interesting. Enough talk, let's get down to coding.
Component configuration for application
After seeing the title of this paragraph your first thought should be, “Hold on a second. Didn’t we use the component last time? So, what else is left for configuring?” Yes, we did. But we used global configuration. When Dapr gets installed on a machine, it creates components with a global, default configuration. As we saw, this configuration can be used from anywhere on this machine.
However, here's the catch. The fact that we can do something doesn’t necessarily mean we should. The same goes for databases, for example. We can, theoretically, use one database for all the applications. But we all know that that is tech heresy. The same goes with Dapr. We should create dedicated elements based on current needs rather than default ones. The elements are configured using the YAML language. If you don’t know what it is, please visit https://yaml.org/.
In this example, we are going to use the Dapr storage component. We will be using a storage component configured exclusively for our needs. Just a little side note, feel free to code with me. In this series, I won’t be describing the entire solution, just the pieces of the utmost value. Nevertheless, these pieces are enough to run all the examples. To make it easier for you, I will present the solution I’m working with. The solution was created using the Rider tool.
The component definition is created in Dapr/components folders. The names of the folders are not mandatory. Inside the folders, I placed the YAML component definition. The file name is stateStore.yml. Let’s take a look at what is inside.
The file is short and easy to read so I won’t be going over all the lines. Two of them are of most interest to us: the store name and the host data. We use both of them when we need to reach the component. In this case, we are going to use the store name because we will go with the SDK in favour of HTTP requests.
In this example, we are going to use a simple asp.net core web application. I’m not going to describe the details of what the project is. The better solution is to show you the project file.
The goal of this application is to use the Dapr store component to write and read data. We will accomplish it using the Dapr SDK. It is much easier to use the raw HTTP requests. The best way to get an SDK is with the NuGet package. All the Dapr packages can be found here.
The one that is of interest to us is the second from the top – Dapr.AspNetCore. Now we need to install it in our project. After installing the package, all we need to do is add Dapr functionalities to our application. We need to do it inside Program.cs file.
The Program.cs file should look like this. Our modification took place in the third line. All we did was call the AddDapr method on the IMvcBuilder object that was returned by calling the AddControllers method. Now we can inject Dapr-related elements into our constructors.
To see how it works, we are going to create a test controller. In the next blog posts, we will extend this example to utilise microservices. For this post, we need to create DaprTestController.cs file. The code inside that file should look something like this.
When it comes to code construction, it is all standard controller. The interesting part is that it uses Dapr elements. We can see the DaprClient instance being injected inside of a constructor. Plus the Dapr state functionalities are being invoked via this client. Operations on the storage are simple key-value pair operations. Please notice that each operation requires a component name. That is very important if you aren’t using global ones or have many components of the same Dapr component type.
Running the Application
All the infrastructural elements are in place. The time has come to set it all into motion. This part is a little tricky. Mainly because we hide to run the application “behind” the Dapr. The best way to do it is with PowerShell. Here is the file, that in my case is placed inside the API project. You can see it in the solution image (the first image in this blog post). The PowerShell (runStoreAPI.ps1) file is presented down below.
In this PowerShell command, we tell Dapr to run. The tricky part is in the parameters setup. I’m referring to the last two of them. The components-path parameter tells the run comment where to look for the definition of the components. .NET run is the last parameter that is to run the application that is to be “hidden” behind the Dapr infrastructure.
What we need to do now is to run this ps1 file while being in the project folder. In my case, the PowerShell command looks like this: PS C:\SH\Blog\Dapr\DaprBlogDemo\StoreAPI> .\runStoreAPI.ps1.
Please keep in mind that Docker needs to be running for Dapr to run. After this command is executed, we should see something like this.
Now we can access the https://localhost:7068/swagger/index.html and check if the solution is working. To do it we need to try to set and get value. In this case, my value will be 13.
The set the operation…
… and the get.
Great success! We have victoriously used the Dapr component to store and retrieve a value. This proves the point that Dapr is working as a layer in front of our application.
That was a lot of work! Good job, if you made it to the end. We managed to configure the Dapr component intended for our application. We introduced Dapr elements to the application code and run the application with the Dapr layer.
Till next time. Keep coding.