Set asynchronous communication between Functions
This tutorial demonstrates how to connect two Functions asynchronously. It is based on the in-cluster Eventing example.
The example provides a very simple scenario of asynchronous communication between two Functions. The first Function accepts the incoming traffic via HTTP, sanitizes the payload, and publishes the content as an in-cluster event using Kyma Eventing. The second Function is a message receiver. It subscribes to the given event type and stores the payload.
This tutorial shows only one possible use case. There are many more use cases on how to orchestrate your application logic into specialized Functions and benefit from decoupled, re-usable components and event-driven architecture.
Prerequisites
- Kyma CLI
- Kyma installed locally or on a cluster
- Istio sidecar injection enabled in the Namespace in which you want to deploy the Functions
Steps
- Export the
KUBECONFIG
variable:Click to copyexport KUBECONFIG={KUBECONFIG_PATH} - Create the
emitter
andreceiver
folders in your project.
Create the emitter Function
Go to the
emitter
folder and run Kyma CLIinit
command to initialize the scaffold for your first Function:Click to copykyma init functionThe
init
command creates these files in your workspace folder:
config.yaml
with the Function's configurationNOTE: See the detailed description of all fields available in the
config.yaml
file.handler.js
with the Function's code and the simple "Hello Serverless" logicpackage.json
with the Function's dependencies
In the
config.yaml
file, configure an APIRule to expose your Function to the incoming traffic over HTTP. Provide the subdomain name in thehost
property:Click to copyapiRules:- name: incoming-http-triggerservice:host: incomingrules:- methods:- GETaccessStrategies:- handler: allowProvide your Function logic in the
handler.js
file:NOTE: In this example, there's no sanitization logic. The
sanitize
Function is just a placeholder.Click to copymodule.exports = {main: async function (event, context) {let sanitisedData = sanitise(event.data)const eventType = "sap.kyma.custom.acme.payload.sanitised.v1";const eventSource = "kyma";return await event.emitCloudEvent(eventType, eventSource, sanitisedData).then(resp => {return "Event sent";}).catch(err=> {console.error(err)return err;});}}let sanitise = (data)=>{console.log(`sanitising data...`)console.log(data)return data}NOTE: The
sap.kyma.custom.acme.payload.sanitised.v1
is a sample event type declared by the emitter Function when publishing events. You can choose a different one that better suits your use case. Keep in mind the constraints described on the Event names page. The receiver subscribes to the event type to consume the events.NOTE: The event object provides convenience functions to build and publish events. To send the event, build the Cloud Event. To learn more, read Function's specification. In addition, your eventOut.source key must point to
“kyma”
to use Kyma in-cluster Eventing. NOTE: There is arequire('axios')
line even though the Function code is not using it directly. This is needed for the auto-instrumentation to properly handle the outgoing requests sent using thepublishCloudEvent
method (which usesaxios
library under the hood). Without theaxios
import the Function still works, but the published events are not reflected in Jaeger.Apply your emitter Function:
Click to copykyma apply functionYour Function is now built and deployed in Kyma runtime. Kyma exposes it through the APIRule. The incoming payloads are processed by your emitter Function. It then sends the sanitized content to the workload that subscribes to the selected event type. In our case, it's the receiver Function.
Test the first Function. Send the payload and see if your HTTP traffic is accepted:
Click to copyexport KYMA_DOMAIN={KYMA_DOMAIN_VARIABLE}curl -X POST https://incoming.${KYMA_DOMAIN}-H 'Content-Type: application/json'-d '{"foo":"bar"}'
Create the receiver Function
Go to your
receiver
folder and run Kyma CLIinit
command to initialize the scaffold for your second Function:Click to copykyma init functionThe
init
command creates the same files as in theemitter
folder.In the
config.yaml
file, configure event types your Function will subscribe to:Click to copyname: event-receivernamespace: defaultruntime: nodejs16source:sourceType: inlinesubscriptions:- name: event-receiverprotocol: ""filer:filters:- eventSource:property: sourcetype: exactvalue: ""eventType:property: typetype: exactvalue: sap.kyma.custom.acme.payload.sanitised.v1- Apply your receiver Function:The Function is configured, built, and deployed in Kyma runtime. The Subscription becomes active and all events with the selected type are processed by the Function.Click to copykyma apply function
Test the whole setup
Send a payload to the first Function. For example, use the POST request mentioned above. As the Functions are joined by the in-cluster Eventing, the payload is processed in sequence by both of your Functions. In the Function's logs, you can see that both sanitization logic (using the first Function) and the storing logic (using the second Function) are executed.