Enterprise Resource Planning Blogs by SAP
Get insights and updates about cloud ERP and RISE with SAP, SAP S/4HANA and SAP S/4HANA Cloud, and more enterprise management capabilities with SAP blog posts.
Showing results for 
Search instead for 
Did you mean: 
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

By definition:
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

The complete code, along with more technical details of this proof of concept, is available on GitHub. Here we are going to overview the main blocks that fits this PoC together.

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.

  1. Loads the timestamp of the last run (#29)

  2. Perform the REST calls to the ByDesign Custom OData Services for the objects whose have the attributes LastChangeDateTime and CreationDateTime (#33)

  3. Publish the response of the previous calls to a message queue (#40)

  4. 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


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.