Should you Upgrade Components API Version

In every new release Salesforce increase the API version by one. The version is relevant for classes/trigger/pages/components and determine which features are available.


For example, if Salesforce added a new field on the Account object in v55 and you need to use this feature, then your code must use v55 or later.


The following code won't compile if trying to save with version lower than 53, as the field Tier was introduce only at v53



public with sharing class AccountService{
	public static List<Account> getAllAccount(){
		return [SELECT Id,Tier FROM Account LIMIT 10];    
	}
}

*Just to clarify, you cannot rely on the compiler, as apex can access fields dynamically!


  • Flow also has an API version, but it should be noted that the features for API versions for Flow are not necessarily synchronized with those for the Apex code. For that reason I left the Flow outside the scope of this article.

Should we always use the latest version? 

When we create a new component it will usually be created with the highest available API version (if it is done using external tool, like vscode, then it might depend on the tool configuration), but is it the right choice?

It is highly recommended that all the code components will use the same API version. Otherwise you might get weird errors in some cases, as one component can access a set of features that are not accessible by other component.

As an example, consider service class that retrieve all the account fields dynamically with v52


public with sharing class AccountService{
    public static List<Account> getAllAccount(){
        String allFields = '';
        
        for(String field : Account.getSobjectType().getDescribe().fields.getMap().keyset()){
            allFields += field + ',';
        }
    
        return Database.query('SELECT ' + allFields.removeEnd(',') + ' FROM Account Limit 10');
    }
}

Other class with API v53 uses this service and try to access the field Tier:


public with sharing class ContactService{

    public static void manageContact(){
        List<Account> accountList = AccountService.getAllAccount();
        for(Account acc : accountList){
            System.debug('Tier:: ' + acc.Tier);
        }
    }
}

Running the method manageContact will result in run time error:

    System.SObjectException: SObject row was retrieved via SOQL

without querying the requested field: Account.Tier


Using the same API across all items will determine if the field Tier is accessible or not.

Of course, if all our code use v52 and per requirement we need to use the Tier field, then we need to upgrade our API version.


Should we upgrade all our previous code when new API version is introduce? 

Most likely it won't be a good idea. Any new API version might contains lots of other changes (included deprecated features), and therefore we must make sure that all our pervious implementation is still working with the new API (full regression!)


  • Be careful during a time when a new Salesforce release is available only in a sandbox. During this period, components can use the new API version, but it will not be possible to deploy them to the production environment, where the new API is not yet available.


You can construct an upgrade plan in your company. For example, upgrade all the components API once in a year or any period that match the company needs and resources, but you don't want to keep using old API version, because over time a new requests come from the business and might require using some new features.


What if the business require development with a new feature right away and your current API doesn't yet support it?


You can do it by developing a standalone class/page/component. Meaning components with the latest version that doesn't has any dependency with other components in your org (those with the lower API).


For example the ContactService class can be developed without referencing the AccountService.

public with sharing class ContactService{

    public static void manageContact(){
        for(String field : Account.getSobjectType().getDescribe().fields.getMap().keyset()){
            allFields += field + ',';
        }
    
        List<Account> accountList = Database.query('SELECT ' + allFields.removeEnd(',') + ' FROM Account Limit 10');
    
        for(Account acc : accountList){
            System.debug('Tier:: ' + acc.Tier);
        }
    }
}


In such case, note it as exception, the reason for the implementation with different version and that this code can be improved in future when you will upgrade all your other code API version.

No comments:

Post a Comment

Retire of Permission on Profiles

If you are working as a Salesforce admin/developer you've probably heard somewhere that Salesforce is planning to make a significant cha...