Composite Application Case Study
The following is a fictitious case study that addresses the need to synchronize data between Salesforce and an external system in near real-time. This case study is intended for Apex developers and managers who would like to understand the potential of the Force.com platform.
Business need:
Custom software producer (Company X) manages very large data sets for their clients (TB+) and wants to tap into the growing Salesforce market with a new AppExchange offering that ties Salesforce data with theirs. Contact data must be synced between their cloud and the Force.com cloud in near real-time. After initial synchronization, changes in Salesforce need to be reflected in their cloud for each client that purchases their product.
Solution:
An AppExchange application is developed to satisfy the business needs. Initial data export from SF involves using the Force.com API but this case study focuses on synchronizing the data once the export has been completed. Ongoing synchronization from Force.com involves database triggers and asynchronous callout methods. A trigger fires on Contact after insert and after update. Trigger instantiates an Apex class (less governor limits than within trigger code) that records data for future synchronization. A separate update class uses a web service or HTTP Post (RESTful) callout, whichever makes more sense for Company X.
I know what you’re all thinking: “That’s IMPOSSIBLE! Even with the reduced governor limits of an Apex class versus an Apex trigger, Salesforce absolutely forbids callouts from anywhere if the initial entry point was a trigger.” Good thinking! This used to be true. However, now you can use the @Future Apex annotation to declare asynchronous callouts that fire when resources are available. You can expose a web service to receive the results when the data is finished processing at Company X.
A few considerations about the @Future keyword:
- You can have no more than 10 @Future calls per Apex invocation.
- There is a limit of 200 @Future calls per Salesforce license per 24 hours.
- @Future parameters must be primitive dataypes, arrays of primitive datatypes, or collections of primitive datatypes.
- Methods with the future annotation cannot take sObjects or objects as arguments.
- Methods with the future annotation cannot be used in Visualforce controllers in either getMethodName or setMethodName methods, nor in the constructor.
Considering the limitations of functions leveraging the asynchronous @Future keyword, one possible method to accomplish the goals of this case study is to store all update data that needs to transfer over the web to Company X’s cloud and read it from the Salesforce database in the @Future function. This eliminates the need to pass in sObjects or other complex data to the function. When the insert or update trigger fires the appropriate data is written to the “update” table. Then either a user initiated synchronization can transfer the new/changed records (via Visualforce page button, for example) or a timed based process can fire – such as Company X calling in via a web service and telling the AppExchange program to wake up and send the latest changes. The @Future function might look something like this:

This function can be called from a trigger that was fired from a Contact insert/update since the execution happens in the @Future and the parameters passed in are primitive data types.
Related posts:


