Till now, we have seen two Dapr building blocks which are the service to service invocation building block and the secrets building block. The secret building block serves to protect things like a database connection string, an API key… so that they’re never disclosed outside of the application. The service to service invocation building block serves to make calls between services in your distributed application easy. In this post, we will introduce a third one which is the bindings building block. The bindings building block enables your distributed application to handle external events or invoke external services.

Introduction

Today’s applications often need to be called from other external applications or call external services.

A binding provides a bi-directional connection to an external cloud/on-premise service or system. Dapr allows you to invoke the external service through the Dapr binding API, and it allows your application to be triggered by events sent by the connected service.

What is the difference between just being called or calling yourself the external service? Like for previous building blocks the benefits are mostly similar

  • Focus on your business logic and avoid implementation details of how to interact with an external system keeping your code free from other SDKs or third parties libraries
  • Being able to swap between Dapr bindings for different environments without any code change
  • Having not to care about the handling of retries and failure recoveries

Sample application

We will implement a very simple application that will poll an external Time service on a configured interval to get the current time in that place. To achieve that we will use two Dapr bindings

  1. An input Cron binding
  2. An output HTTP binding

As previously those are configured in the dapr/components folder.

scheduleHttpJobCron.yaml
1
2
3
4
5
6
7
8
9
10
11
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: scheduleHttpJob
namespace: default
spec:
type: bindings.cron
version: v1
metadata:
- name: schedule
value: "@every 10s"

The Dapr Cron binding named scheduleHttpJob will be triggering each 10 seconds.

httpJob.yaml
1
2
3
4
5
6
7
8
9
10
11
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: httpJob
namespace: default
spec:
type: bindings.http
version: v1
metadata:
- name: url
value: http://worldtimeapi.org/api/timezone/Europe/Paris

The Dapr Http binding named httpJob will call the WorldTimeAPI service to get the current time in Paris.

Now that we have the Dapr configurations done, we need to have some code that will be called when the scheduleHttpJob is triggered.

To tie together the two Dapr bindings we create an ASP.NET controller that will be called by the scheduleHttpJob binding using an HTTP POST on the route scheduleHttpJob. The controller will use the httpJob binding to call the external service.

ScheduledHttpJobController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[Route("scheduleHttpJob")]
[ApiController]
public class ScheduledHttpJobController : ControllerBase
{
private readonly ILogger<ScheduledHttpJobController> _logger;
private readonly DaprClient _daprClient;

public ScheduledHttpJobController(ILogger<ScheduledHttpJobController> logger,
DaprClient daprClient)
{
_logger = logger;
_daprClient = daprClient;
}

[HttpPost]
public async Task HttpJob()
{
_logger.LogInformation($"{nameof(ScheduledHttpJobController)} called 😎");

var response =
await _daprClient.InvokeBindingAsync(new BindingRequest("httpJob", "get"));
var timeData = JsonSerializer.Deserialize<TimeData>(response.Data.Span);

_logger.LogInformation($"⏰ in Paris {timeData?.utc_datetime}");
}
}

Starting the application

A start.ps1 script is provided in the GitHub repository. It will start the ASP.NET application and the Dapr sidecar.

And here are the results displayed after starting the application and waiting ten seconds that the cron input binding triggers and call the ASP.NET controller

1
2
3
4
== APP == info: Worker.Controllers.ScheduledHttpJobController[0]
== APP == ScheduledHttpJobController called 😎
== APP == info: Worker.Controllers.ScheduledHttpJobController[0]
== APP == ⏰ in Paris 10/19/2021 1:29:04 PM

Conclusion

We have seen that Dapr provides a great way to integrate with external systems using its binding building block. By leveraging Dapr building blocks your code becomes independent from the external systems you are integrating with keeping your code free from SDKs or third parties libraries. We will see that in a future post showing the integration of an external system using GraphQL.

You can get access to the code of this blog post on GitHub in the CronHttpBindings folder.