These days I have had the chance of playing with the new Salesforce functionality called Platform Events. Platform Events allows you to publish and subscribe to events that are distributed over channels on the platform in a really cool way. Platform Events has been made Generally Available in summer 17.
#1 Platform Events opens the door to an event driven architecture
Platform Events publish / subscribe model allows a high level of decoupling and extensibility. Publishers don’t know anything about subscribers, and subscribers don’t know anything about publishers. This gives us the possibility of implementing an event driven architecture, which is suitable for large distributed systems.
#2 Events are defined in the same way as sObjects, but they have differences
Events are defined in a screen very similar to the sObjects one. Their API name ends in __e. Fields can be defined for an event, in order it can carry information, but only certain field types are allowed (Checkbox, Date, Date/Time, Number, Text, Text Area(Long) ).
Also, not all the functionality from sObjects applies to events, for example you cannot create layouts or record types for them.
CRUD & FLS can be defined for platform events, to indicate which users are allowed to publish an event, for example.
In contrast to sObjects, Events are not queryable, and I do not think they will be in the future. All of this makes sense, as although they resemble sObjects, they are really events that occur in time, not database records. Once they have been published, they are not editable either.
#3 Event publishers / subscribers can be defined on and off platform
This is a key benefit of events. Events can be published:
- Within Salesforce, creating Event instances, as if they were common sObjects, and publishing them. Here you have an example of how to do it:
ItemScanned__e itemToScan = new ItemScanned__e(); itemToScan.WarehouseName__c = 'Warehouse ABC'; Database.SaveResult result = EventBus.publish(itemToScan);
- Off platform, using any of the APIs that can be normally used to create sObjects: REST API, SOAP API, Bulk API… Here you have an example of how to publish an event using REST API in workbench:
We can subscribe to events:
- Within Salesforce, creating events triggers. These triggers only respond to the after insert trigger event, and can read the Event record information (its field values) and perform some actions accordingly.
- Off platform, using the Streaming API. More on this later.
This can led to very powerful and flexible integrations.
#4 Events order of delivery for a specific channel is guaranteed
A channel exists for each defined event, and when Events are published, Event instances are placed on those channels. The order of delivery of Events and their delivery itself are guaranteed according Salesforce documentation.
#5 Apex subscribers (triggers) are run as the “Automated Process” user
This fact has some implications that worth to mention:
- If you want to debug an Event trigger subscription, you will have to setup the debug logs for such user.
- Any CRUD, FLS or sharing rules will be enforced. Currently, the only workaround is to make sure the apex code only did the minimal set of actions that were allowed for users who have create access to the event entity.
- You will need to take care of error handling in the trigger subscriber, for example sending an email notification or logging to an sObject.
#6 Events can be refired in Apex subscribers
Events can be refired in triggers using:
throw new EventBus.RetryableException();
The system resends events after a small delay, which increases on each subsequent retry. A resent event has the same field values as the original event, but the batch size of the events can be different.
#7 Off platform subscriptions are done through Streaming API using cometD protocol
As I mentioned before, the way of subscribing to events from an external application is the same that Streaming API push topic subscriptions.
Each platform event that you create corresponds to a channel in CometD. The channel name is the name of the event prefixed with “/event/”, for example, /event/ItemScanned__e. A Bayeux client can receive streamed events on this channel.
Basically what happens is that after a handshaking phase, the client connects and requests information from the server. However, instead of sending an empty response if information isn’t available, the server holds the request and waits until information is available (an event occurs). The server then sends a complete response to the client. The client then immediately re-requests information. The client continually maintains a connection to the server, so it’s always waiting to receive a response. In the case of server timeouts, the client connects again and starts over.
There is an open source library called EMP connector that uses cometD protocol behind the scenes and allows you to easily subscribe to Events in Java.
Worth to mention that it is in Salesforce roadmap supporting more protocols apart from cometD in the future.
#8 Off platform subscribers can consult events occurred in the last 24 hours
Each event instance has a unique replay Id that identifies its position in the channel.
When subscribing to an event, you can set the ReplayId parameter in order to determine from which point in time do you want to receive publications of a specific event. You can specify:
- A previous event Replay Id you want to replay from
- -1: you subscribe from the tip, which means you subscribe for any new messages that come in
- -2: you want to get everything that was sent in the last 24 hours (Salesforce is thinking of extending this period).
#9 Platform Events are non transactional
If the transaction that publishes an Event fails, the Event will be delivered anyway. This is, Event publication cannot be rolled back, and acts differently as database insertions in Salesforce.
#10 High volumes is on the roadmap.
Per Salesforce documentation, it is in their roadmap to support High Volume Platform Events. I hope to hear soon about this.
In conclusion, Platform Events is a really powerful feature, which is in still in an early stage, but which I am sure Salesforce will empower in the next releases, as it provides a nice way of creating performant distributed event driven solutions with contributors in and off platform.