Technical Articles
External Event Pulling – A Decoupled Approach for SAP Business ByDesign Event Handling
Following our series of blog posts about approaches for event handling in SAP Business ByDesign, I would like to present an alternative that makes no use of internal components. That means no Cloud Application Studio artifacts or SAP Business ByDesign specific configurations.
This gives us great flexibility and allows us to easily do stuff like this:
Loosely Coupled Architectures
A loosely coupled system is one in which each of its components has, or makes use of, little or no knowledge of the definitions of other separate components.
Our goal is to create a solution that has little interdependency with SAP Business ByDesign. So it can scale and be enhanced at its own pace. This architecture also provides much more flexibility in terms of runtime choices, services, and UX. You are free to make those choices.
In short, ByDesign should act as a black box, surrounded by APIs providing the data entry points your app, that implements whatever tech you want, requires.
We have written tons of articles, code samples, and presented webinars showing use cases in favor of decoupled architectures. If you are not familiar with the said approach, I suggest this overview session as a starting point. You will understand its advantages and how it goes hand-in-hand with cloud-native solutions (which, SPOILER ALERT, your CAS solution is not).
External Event Pulling Implementation
Since all the action happens outside SAP Business ByDesign, we need a mechanism to periodically pull information from the system. That’s the role of the serverless function get-byd-objects.
This snippet, in the function’s handler, summarizes well enough what’s happening.
- Loads the timestamp of the last run (#29)
- Perform the REST calls to the ByDesign Custom OData Services for the objects whose have the attributes LastChangeDateTime and CreationDateTime (#33)
- Publish the response of the previous calls to a message queue (#40)
- Updates the last run new timestamp (#41)
Since our components are decoupled, that’s all the job this function has to do. Everything onwards is going to be triggered by the events it generates. Nice to meet you, event-driven architecture.
Publish-Subscribe Pattern
On step #3, we published messages into a Pub/Sub messaging service.
This is a simple (yet very powerful) piece that will broadcast every received message to an infinite number of subscribers. It offers an asynchronous, serverless, and often codeless alternative for service-to-service communication.
There are plenty of options out there, like SAP Cloud Platform Enterprise Messaging, Azure Service Bus, Google Pub/Sub, AWS SNS, just to name a few.
{
ObjectID: '00163E71D7E21EEABF9A8DD263CAF2B0',
ID: '1INV-12-2020',
CreationDateTime: '/Date(1600779993000)/',
LastChangeDateTime: '/Date(1600779993000)/',
GenericId: '1INV-12-2020',
Updated: false,
GenericType: 'CustomerInvoice',
DateStr: 2020-09-22T13:06:33.000Z
}
A message like this will be broadcasted
Subscribers
For this proof of concept, I have implemented 2 subscribers. Both serverless functions that will act upon receiving a message.
The first of them, publish-event-scp, will receive the whole content of a message and pass it on to SAP Cloud Platform Enterprise Messaging. This ishe entry point for another proof of concept explained on a separate blog. Nevertheless, we have here a great example of how different applications can communicate, asynchrronously, using event-driven architectures.
The second subscriber, tweet-byd-event, formats a text with the received message information and tweet it using our ByDEventBot
Extending the code to cover other ByDesing objects
The event pulling will be limited by the number of business objects you wish to support. However, following the KISS principle, I tried to make it as simpler as I could for you to extend.
Let’s see what I’ve done to get-byd-objects to support Service Orders (which I used for the video above).
1 – Create a new promise for the newly supported object. This will specify the ByD OData endpoint and its primary key name. In the code below, both are environment variables (BYD_SERVICEORDERS and BYD_SERVICEORDERS_ID).
2 – Add the new promise call to the geyBydObjectsPromises array.
You can see it in this commit or when I needed to also support the Sales Documents.
Implementation Choice
There are many options to implement the architecture proposed in this blog post. This time, I decided to go with AWS and built a completely serverless solution. This architecture can support workloads ad infinitum and also is an example of how we can plug SAP Business ByDesign to the external world.
You will find a detailed installation guide, so you can deploy this proof of concept, on GitHub.
If you reached this part, thanks for reading, and hope you have enjoyed it. Let me know your comments below and feel free to ping me on Twitter. @Ralphive.