Effective Callouts Using Platform Cache

Salesforce introduced a new feature that involves multiple decision criteria in single Process Builder. Before summer 16, Process Builder can have only one criteria with true or false condition. If the first criterion is not satisfied, it will move to the second criteria

In Winter ’16 Salesforce released a feature named Platform Cache, a memory layer that provides faster performance and better reliability when caching Salesforce user’s session and org data. We can specify what to cache and for how long (Time to Live) without using custom objects and settings or overloading the Visualforce view state. By distributing cache space across various applications or operations, Platform Cache improves performance such that cache capacity cannot be stolen by other applications or processes.

Platform Cache 

Platform Cache is a memory layer that stores Salesforce session and org data for future use. Applications run faster, when we use Platform Cache because they store reusable memory. They can access this data quickly and they don’t need to duplicate calculations and requests to the database on subsequent transactions.

Types of Platform Cache: 

1.Org Cache 

Org cache can store Org-wide data such that anyone in the Org can access it. Org cache is accessible across sessions, requests, and org users and profiles. For org cache, data can live up to 48 hours in the cache. By default, the time-to-live(TTL) value for org cache is 24 hours.

2.Session Cache 

Session cache stores data that are tied to a user’s session such that other users in the Org cannot access this data. The maximum life of a session cache is 8 hours.

Creating Platform Cache Partition: 

By default, our Developer org has 0 MB cache capacity. We can request a trial cache of 10 MB. To request a trial, click Your Name [Symbol] Setup [Symbol] Develop [Symbol] Platform Cache[Symbol] New Platform Cache Partition.

Requesting Trial Capacity for Platform Cache: 

Platform Cache

Provide a suitable Name, and Label for the partition. 

Specifying available Cache capacity:  

Platform Cache

Check default partition checkbox to use your cache name directly in Apex codes, without the namespace prefix.

If the trial cache capacity is available, then specify the capacity for both session cache and org cache.

Note: Sum of both the session and org cache capacity should be equal to the total available cache capacity. (Minimum Capacity is 5 MB)

Store/Retrieve Data in Org Cache: 

To store values in an Org Cache use put(<CacheNameKey>,<Value>); and to retrieve values from an Org Cache we can use get(<CacheNameKey>);

  1. // Get partition
  2. Cache.OrgPartition orgPart = Cache.Org.getPartition(‘local.CurrencyCache’);
  3. // Add cache value to the partition
  4. orgPart.put(‘DollarToEuroRate’, ’0.91′);
  5. // Retrieve cache value from the partition
  6. String cachedData = (String)orgPart.get(‘DollarToEuroRate’);
  7.  System.assertEquals(‘0.91’, cachedData);

Store/Retrieve Data in Session Cache: 

We can use the Cache.Session and Cache.SessionPartition classes to manage values in the session cache. For managing values in any partition, use the methods in the Cache.Session class. If managing cache values are in one partition, use the Cache.SessionPartition methods instead.

Using Cache.Session: 

To store a value in the session cache, call the Cache.Session.put() method and provide a key and value. The key name is in the format namespace.partition.key. To retrieve, use the key in the cache.Session.get() method.

  1. String username = ‘DemoUser’;
  2. // Add a value to the cache
  3. Cache.Session.put(‘local.MyCache.usernameCache’, username);
  4. if (Cache.Session.contains(‘local.MyCache.usernameCache’)) {
  5. // Retrieve value from the cache
  6.     String cachedData = (String)Cache.Session.get(‘local.MyCache.usernameCache’);
  7.     System.assertEquals(username, cachedData);
  8. }

Using Cache.SessionPartition: 

To store a value in the session cache, call the Cache.Session.put() method and provide a key and value. The key name is in the format namespace.partition.key.

  1. // Get partition
  2. Cache.SessionPartition sessionPart = Cache.Session.getPartition(‘local.CurrencyCache’);
  3. // Add cache value to the partition
  4. sessionPart.put(‘FavoriteCurrency’, ’JPY’);
  5. // Retrieve cache value from the partition
  6. String cachedRate = (String)sessionPart.get(‘FavoriteCurrency’);

Storing Callout responses in a Platform Cache: 

Now we implement this Platform Cache in a useful scenario – storing weather data temporarily in a platform cache. When a user request for weather details for a city for the first time from Salesforce, a callout is sent to a web service to fetch the weather details and the data is stored in platform cache with a specific time-to-live, say 6 hours. When the user requests again for the same city within that 6 hours, data is fetched from Platform Cache rather than sending callouts to web service.

Apex Visual Page (FetchWeather_VF): 

  1. <apex:page controller=”FetchWeatherController”>
  2.     <apex:sectionHeader title=”Fetch Weather Report” subtitle=”Select City”/>
  3.     <apex:form>
  4.         <apex:selectList size=”1″ value=”{! selectedCity}”>
  5.             <apex:selectOptions value=”{! allUScities}”></apex:selectOptions>
  6.         </apex:selectList>
  7.        <apex:commandButton action=”{! retrieveWeatherDetails}” value=”Get Weather”/>
  8.        <apex:outputPanel rendered=”{! IF(combinedResultsList.size != 0, TRUE, FALSE)}”>
  9.             <apex:pageBlock tabStyle=”Contact”>
  10.                 <apex:pageBlockSection title=”{! selectedCity}’s Current weather”>
  11.       <h3>Temperature </h3><apex:outputText value=”{! combinedResultsList[0]} K” />
  12.       <h3>Pressure </h3><apex:outputText value=”{! combinedResultsList[1]}” />
  13.       <h3>Humidity </h3><apex:outputText value=”{! combinedResultsList[2]} %” />
  14.       <h3>Min Temperature </h3><apex:outputText value=”{! combinedResultsList[3]} K” />
  15.       <h3>Max Temperature </h3><apex:outputText value=”{! combinedResultsList[4]} K” />
  16.                 </apex:pageBlockSection>
  17.             </apex:pageBlock>
  18.         </apex:outputPanel>
  19.     </apex:form>
  20. </apex:page>

Apex Controller Class (FetchWeatherController): 

  1. public class FetchWeatherController
  2. {
  3.     public String[] combinedResultsList { get; set; }
  4.     public String selectedCity { get; set; }
  5.     private static String cachename = ’WeatherCache’;
  6.     private static String apiKey = ”;
  7.     private static String endPointURL= ”;
  8.     public Cache.SessionPartition thisSession;
  9.     private Cache.SessionPartition getPartition()
  10.     {
  11.         if(thisSession == null)
  12.             thisSession = Cache.Session.getPartition(cacheName);
  13.         return thisSession;
  14.     }
  15.     public SelectOption[] allUScities { get
  16.     {
  17.         allUScities = new List<SelectOption>();
  18.         for(US_Cities__c option : US_Cities__c.getAll().values())
  19.             allUScities.add(new SelectOption(option.City_API__c,option.Name));
  20.         return allUScities;
  21.     } private set;}
  22.     public void initializeAPI()
  23.     {
  24.         apiKey = ’XxxxxxxxxxxxxxxxxxxxxxxxxxxxxxX’;
  25.         endPointURL = ’http://api.openweathermap.org/data/2.5/weather’;
  26.         combinedResultsList = new List<String>();
  27.         thisSession = getPartition();
  28.     }
  29.     public FetchWeatherController()
  30.     {
  31.         combinedResultsList = new List<String>();
  32.         thisSession = getPartition();
  33.     }
  34.     public void retrieveWeatherDetails()
  35.     {
  36.         initializeAPI();
  37.         endPointURL += ’?q=’+selectedCity;
  38.         endPointURL += ’&APPID=’ + apiKey;
  39.         if(thisSession.contains(selectedCity))
  40.         {
  41.             combinedResultsList.addAll((List<String>)thisSession.get(selectedCity));
  42.             return;
  43.         }
  44.         else
  45.         {
  46.             // Instantiate a new http object
  47.             Http h = new Http();
  48.     // Instantiate a new HTTP request, specify the method (GET) as well as the endpoint
  49.             HttpRequest req = new HttpRequest();
  50.             req.setEndpoint(endPointURL);
  51.             req.setMethod(‘GET’);
  52.             // Send the request, and return a response
  53.             HttpResponse res = h.send(req);
  54.             System.debug(”+res.getBody()+’ Code: ’+res.getStatusCode());
  55.             if (res.getStatusCode() == 200)
  56.             {
  57.                 Map<String, Object> resultsMap = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
  58.                 Map<String, Object> mainResultsMap = (Map<String, Object>)(resultsMap.get(‘main’));
  59.                 combinedResultsList.add(String.valueOf(mainResultsMap.get(‘temp’)));
  60.                combinedResultsList.add(String.valueOf(mainResultsMap.get(‘pressure’)));
  61.                combinedResultsList.add(String.valueOf(mainResultsMap.get(‘humidity’)));
  62.                combinedResultsList.add(String.valueOf(mainResultsMap.get(‘temp_min’)));
  63.                combinedResultsList.add(String.valueOf(mainResultsMap.get(‘temp_max’)));
  64.                 thisSession.put(selectedCity,combinedResultsList, 21600);
  65.             }
  66.             if(combinedResultsList.isEmpty())
  67.             {
  68.                 combinedResultsList = new List<String>{‘Data Not available’,’Data Not available’,’Data Not available’,’Data Not available’,’Data Not available’};
  69.             }
  70.         }
  71.     }
  72. }

Notes: 

Using Platform Cache, we can replace custom settings or custom metadata, and, we can set Time-to-Live (TTL) for each data we store, which is an added advantage.

In the above scenario, we have minimized usage of web callouts, by retrieving temporary data from platform cache rather than callouts.

Similarly, we can store sObjects, SOQL queries, or any other data types in Platform Cache.

We can diagnose the performance of using platform cache in the following option:

Click Your Name [Symbol] Setup [Symbol] Develop [Symbol] Platform Cache [Symbol] <Your Platform Cache Name> [Symbol] Diagnostics

Diagnosing Cache usage: 

Platform Cache

Limits of Platform Cache: 

Cache Allocations by Edition: 

Platform Cache is available for Enterprise Edition orgs and above. These are the following editions that come with some default cache space. We can increase number of cache for greater performance enhancements.

  • Enterprise Edition (10 MB by default)
  • Unlimited Edition (30 MB by default)
  • Performance Edition (30 MB by default)
  • Developer Edition (request Trial capacity for 10 MB, 0 MB by default)
LIMITSSESSION CACHEORG CACHE
Minimum partition size5 MB5 MB
Maximum size of a single cached item100 KB100 KB
Maximum local cache size for a partition, per-request500 KB1000 KB
Minimum time-to-live300 seconds (5 minutes)300 seconds (5 minutes)
Maximum time-to-live28,800 seconds (8 hours)172,800 seconds (48 hours)
Default cache time-to-live28,800 seconds (8 hours)86,400 seconds (24 hours)

Conclusion: 

Platform Cache can increase performance, replace Custom Settings and Custom Meta Data Types by storing data temporarily without any need of extra storage, and eliminates the need to use web callouts (as per our scenario).

References: 

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_platform_cache_limits.htm
https://trailhead.salesforce.com/modules/platform_cache

About MST

At MST Solutions our cornerstone is to adapt, engage and create solutions which guarantee the success of our clients. The talent of our team and experiences in varied business verticals gives us an advantage over other competitors.

Recent Articles

Work with us.

Our people aren’t just employees, they are key to the success of our business. We recognize the strengths of each individual and allow them time and resources to further develop those skills, crafting a culture of leaders who are passionate about where they are going within our organization.