sapui5tutors SAPUI5 • Fiori • SAP BTP Step-by-step tutorials Real project examples Interview Q&A
Practical SAPUI5 • Fiori • SAP BTP tutorials and interview prep

CAPM Messaging: Async Events with SAP Event Mesh

Stop polling, start emitting

Synchronous OData calls couple systems tightly: if the receiver is down, the sender fails. Asynchronous messaging through SAP Event Mesh decouples them — emit an event, move on, let subscribers catch up.

Use messaging when: the receiver doesn't need an immediate answer, multiple systems care about the change, or the receiver might be temporarily unavailable.


The outbox pattern: reliable emitting

CAP's killer feature for messaging is the transactional outbox: events are written to a database table in the same transaction as your business data, then forwarded to the broker asynchronously.

// in package.json cds.requires
"messaging": {
  "kind": "enterprise-messaging-shared"
}

No lost events on crashes, no dual-write problem. If the transaction commits, the event is guaranteed to be delivered.


Emitting events

Define the event in your service, then emit it from a handler:

service OrderService {
  entity Orders as projection on my.Orders;
  event OrderApproved : { orderID : String; };
}
this.on('approve', 'Orders', async (req) => {
  // ... approve logic ...
  const messaging = await cds.connect.to('messaging');
  await messaging.emit('OrderService/OrderApproved', {
    orderID: req.params[0].ID
  });
});

The emit writes to the outbox table; CAP's messaging service forwards it to Event Mesh in the background.


Subscribing to events

const messaging = await cds.connect.to('messaging');

messaging.on('OrderService/OrderApproved', async (msg) => {
  const { orderID } = msg.data;
  // e.g. trigger downstream fulfillment
});

Handlers receive the event payload and run asynchronously. Failed handling retries with backoff — design handlers to be idempotent, since redelivery can happen.

Idempotency is non-negotiable for message handlers: the same event may arrive twice. Check-then-act on a processed-events record.


Local development without a broker

  • File-based messaging — CAP supports a local file-system broker for development; no Event Mesh instance needed.
  • In-process — emit and subscribe in the same cds watch process to test the full flow.
  • Promote to shared — switch the kind to enterprise-messaging-shared for deployed environments.

Event design guidelines

Good events are facts about the past, not commands about the future: OrderApproved, not ApproveOrder. Subscribers decide what a fact means to them; commands couple the emitter to the receiver's behavior.

Keep payloads self-contained — include the IDs and key attributes a subscriber needs, so it doesn't have to call back synchronously. But don't stuff the entire entity in; large payloads make versioning painful.

Version your events: add fields, never rename or remove them. Old subscribers should ignore what they don't understand. A breaking event change is a coordinated deployment across teams — exactly what messaging was supposed to avoid.


Think in events

Not everything needs to be a synchronous API call. The systems that scale best on BTP are the ones that emit facts and react to them.

Designing an event-driven flow? Sketch it in the comments.