3

As part of integration in AppExchange, we would like to capture Salesforce record changes in external system when some change happens in Salesforce records.

There are multiple ways to inform external system from Salesforce as below:

1. Change Data Capture

2. Push Topics

3. Platform Events

4. Future method/Batch Apex combination of Apex

  • Another way can be to have a future method that will fire from trigger and notify external system. Maximum number of future methods are 250,000 or the number of user licenses multiplied by 200, whichever is greater. This limit is for your entire org and is shared with all asynchronous Apex: Batch Apex, Queueable Apex, scheduled Apex, and future methods.

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_invoking_future_methods.htm

Question: Considering multiple customer org with below consideration, is there any recommended way to capture the record changes in the Salesforce AppExchange apps? Or as a Product the App should support all ways of sync and let customer 's admin took the decision of what feature they want to use to capture the changes?

  • Different Salesforce editions (Enterprise, Unlimited, Professional, etc.)
  • Existing implementation that may be using CDC, Push Topics, Platform Event or Batch Apex
  • Daily bulk import in some of the customers orgs from external system
  • Dependency of feature (Push Topic, CDC, Platform Event) in customer org.

1 Answer 1

1

NB: This is at least in part opinion-based, but here's my tuppence worth based on our experience.

I cannot really answer with allowing use on a Professional edition org since we don't have customers using our managed package on such an org (and I doubt we support it). Otherwise, my answer is to leave that entirely up to the implementer, especially if the external system varies from subscriber to subscriber. They will know what else is in use on the org, and where limits may be impacted.

If it needs to be "built in" to the app, use of platform events from a trigger would be my recommendation, with a trigger-based subscriber that takes chunks of event(s) and formulates the required callouts, ensuring to adhere to callout limits in each execution. There are possible down-sides, including loss of platform events where there are catastrophic faults in the org infrastructure, though these should be rare and, using after commit publish behaviour, may not happen at all.

On your suggestions, option 4 is a complete no-go and a design anti-pattern; while you have a limit of 50 new futures in a given synchronous transaction (so can possibly just handle a full insert/update of 10000 records in one go) this is no good for where some subscriber implementation happens to commit more than 200 record changes in one go in an async context. Take a look for Maximum number of methods with the future annotation allowed per Apex invocation (and Maximum number of Apex jobs added to the queue with System.enqueueJob in case you consider queueables in the same way) in the documentation. Remember that triggers are called with chunks of at most 200 records, but all invocations are part of the same transaction.

2
  • Hi Phil, Thanks a lot for detailed answer. Just to provide more details on Approach 4 is this can be the combination of Future method + Batch apex. Where we check how many records can be handled in a future method (e.g. sending 1000 IDs to external system through a single future method). Then based on threshold number we will decide to future method or a batch apex. As external system is accepting list of IDs in callout, future method will just post the IDs of the records which have been changed.
    – Ashish
    Jun 21, 2021 at 9:07
  • 1
    The problem is that you cannot create a future in the context of a future, and you cannot ensure you only generate the future once all chunks have passed through the trigger. So this is a pattern you simply should not use. Basically never initiate async processing from a trigger - use platform events to get you out of async context back into sync context then initiate the processing you need.
    – Phil W
    Jun 21, 2021 at 10:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .