Dapr is a portable, event-driven runtime that makes it easy for any developer to build resilient, stateless and stateful applications that run on the cloud and edge and embrace the diversity of languages and developer frameworks, Leveraging the benefits of a sidecar architecture, Dapr helps you tackle the challenges that come with building microservices and keeps your code platform agnostic.
Dapr PHP SDK did not work with the latest version of Laravel due to some dependency issues. We needed a way to work natively with Dapr using Dapr’s internal APIs to solve this.
I came across a unique situation where Laravel queues were used on a large scale and published messages to AWS SQS. The organisation wanted to move from AWS to Azure cloud. Now a normal cloud changeover implementation would require creating relevant queues and topics in Azure and then changing all Laravel connections to point to Azure queues. The cloud landscape is changing daily. Businesses prefer the approach to make applications cloud-native. Enter Dapr, which is a runtime that attaches to your container implementation. It is supported on Azure Container apps and also can be deployed to any Kubernetes cluster.
A demonstration of the functionality can be found on GitHub. The example uses a publisher and consumer service to send messages on a Redis queue. The Redis queue can easily be swapped with anything else like Amazon SQS, Azure Service bus etc.
Implementation of Dapr brings flexibility and robustness to the application. Using other services such as service invocations, secrets, actors etc. help to scale applications by keeping event-driven implementations language and cloud agnostic providing flexibility to move application in different clouds.
Let’s start by explaining the architecture with a simple diagram
Dapr connections have been setup declaratively using YAML files
The Key components in the above file:
type: Type of the pub-sub binding for Dapr to forward the message to. Here as I have connected it to Redis the type is pubsub.Redis. Similarly, if the binding was Azure service bus it would be pubsub.azure.servicebus.queues | pubsub.azure.servicebus.topics
metadata: These are the required values to make a successful connection. The above example has Redis details.
kind: This is an internal value for Dapr to understand what the config is about. there are various configs that you can add.
One additional subscribe component is required for the consumer service when creating dapr connections.
Similar to the publish service having publish components the subscriber will need a subscribe component. That is an addition to the publish app declarations above which act as an address for the consumer service to listen on.
The Key components of the consumer service are:
kind: The kind here is Subscription. It specifies that declaration refers to subscription
rules: The rules mechanism above tells dapr where to forward the request to, it can be represented as an API endpoint.
default: default route as the name suggests is the default if none of the rules match
Adding more functionality and endpoints is easy. All that is needed is, adding more endpoints in the above subscribe component. Add the same endpoint to Laravel in the api.php route or web.php routes.
Publishing messages to new endpoints will require the publisher to change type to the new endpoint condition.
For example:
Adding modify service will entail. Adding a rule to above subscribe component.
apiVersion: dapr.io/v2alpha1
kind: Subscription
metadata:
name: subscribe
spec:
topic: orders
routes:
rules:
- match: 'event.type == "create"'
path: /api/dapr/create
- match: 'event.type == "cancel"'
path: /api/dapr/cancel
- match: 'event.type == "modify"'
path: /api/dapr/modify
default: /api/dapr/receive
pubsubname: pubsub-topics
Add an endpoint to Laravel
Route::post('/dapr/modify', [\App\Http\Controllers\DaprController::class, 'DaprModify']);
Fin..
Dapr provides us tools to drive event-driven, fault tolerent architectures. Dapr also is introducing workflows that can statefully do long running tasks. Hope you have learned new stuff and enjoyed this article. Thanks.