1

Scenario:

  1. When a new case record is created or existing case record is updated in Salesforce, we need to send these details to an external system using REST API call.
  2. Sometimes updates happen on same record in a very short duration of time. Case status changed to 'In Progress' at 10AM and then Case status is changed to 'Closed' at 10:01AM.
  3. When updates are happening back to back, our external system is going out of sync. Because the callout from future method for the 10AM update is still in Queued status but future method callout for the 10:01AM update finished.
  4. This is resulting in external system first updating the Case status to 'Closed'(10:01AM update in Salesforce) and then re-opening(10AM update in Salesforce) the case.

Current design:

  1. We have a trigger on Case object and it calls a future method to make API call to external system.

Note: I have looked into Platform Events and it guarantees the order of events but our external system cannot subscribe to the channel. It can only receive REST API calls.

Any better design to solve this problem?

2

Were I in your shoes, my approach would likely be to create a Custom Setting or Custom Object to stage your requests, then batch over them on as short an interval as possible. You can order your batch by CreatedDate and delete the records when finished.

public with sharing class MyBatch implements Database.Batchable<SObject>, Database.Stateful
{
    @TestVisible static Boolean chainBatches = true;

    final List<Id> successes = new List<Id>();

    public Database.QueryLocator start(Database.BatchableContext context)
    {
        return Databsae.getQueryLocator([
            SELECT ... FROM PendingSync__c
            ORDER BY CreatedDate
        ]);
    }
    public void execute(Databse.BatchableContext context, List<PendingSync__c> changes)
    {
        // make callouts
        // record successes
    }
    public void finish(Database.BatchableContext context)
    {
        Database.delete(successes);
        if (chainBatches)
        {
            system.scheduleBatch(this, 'Some Name ' + Datetime.now().format(), 5);
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.