Apex Code Best Practices
CloudPrism Solutions
Salesforce Consulting Partner | Offering Salesforce CRM services & Resources | Solutions to Your Business Problem
Abstract
Apex code is the Force.com on-demand programming language for developers interested in building the next generation of business applications. Apex enables developers to add business logic to most system events, including button clicks, related record updates, and Visualforce pages. Apex Code can be initiated by Web service requests and from triggers on objects. Some key best practices with any programming language that helps you write efficient and scalable code. This blog is about Apex Code Best Practices.
In this article, we’ll discuss the below mentioned best practices to write and design Apex Code in Salesforce :
#1: Bulkify your Code
Bulkifying?Apex code means making sure your code handles more than one record at a time.
Example of poorly written code that handles only one record at a time.
trigger accountTest on Account (after update) {
?
? ?//This only handles the first record in the Trigger.new collection
? ?Account acc = Trigger.new[0];
? ?List<Contact> contacts = [select id, firstname, lastname, email
from Contact where accountId = :acc.Id];
}
Below is the bulkified code written.
trigger accountTest on Account (after update) {
?
? ?//Create List Collection
List<Id> accIds= new List<Id>();
//Loop through all records in the Trigger.new collection
? ?for(Account acc: Trigger.new) {
accIds.add(acc.Id);
}
? ?List<Contact> contacts = [select id, firstname, lastname, email
from Contact where accountId IN :accIds];
}
The above version of code iterates across the entire “Trigger.new” collection with for loop. If this Trigger is invoked with up to 200 Accounts, all records are properly processed.
#2: Avoid SOQL Queries or DML statements inside FOR Loops
Governor limits are calculated at runtime. After the request is initiated, any Apex code executed in that transaction applies and shares the governor limits.
Per-transaction Apex Limits
Total number of SOQL Queries: 100 (Sync) | 200 (Async)
Total number of records retrieved: 50K
Total number of DML statements: 150
Total number of records processed by DML: 10K
Maximum SOQL query runtime before Salesforce cancels the transaction: 120 seconds
Poor Code :
trigger GetContacts on Accounts (after insert, after update) {
for(Account a : Trigger.new){
List c = [SELECT Id FROM Contact WHERE AccountId = a.Id];
}
}
Optimal Way :
trigger GetContacts on Accounts (after insert, after update) {
Set ids = Trigger.newMap.keySet();
List c = [SELECT Id FROM Contact WHERE AccountId in :ids];
}
#3: Never call @future/asynchronous methods inside for loop
The @future annotation methods cannot be used in Visualforce controls in GetMethodName or setMethodName methods, not in constructor also. Plans with the future annotation cannot take objects as arguments; it always takes id as argument.
The @future method should be invoked with?the batch of records so that it is only invoked once for all documents it needs to process:
trigger accountAsyncTrigger on Account (after insert, after update) {
? ? //By passing the @future method a set of Ids, it only needs to be
? ? //invoked once to handle all of the data.
? ? someClass.processAccount(Trigger.newMap.keySet());
}
And now the @future records is designed to receive forms:
global class someClass{
@future
? public static void processAccount(Id accountId) {
? // some code here
? ? ? ? ? }
}
#4: Avoid Hardcoding IDs
In Salesforce, Hardcode IDs should be avoided, the code should be written to fetch the record IDs dynamically. If the record ID’s are changed between two different environments, the logic can dynamically identify the correct data without failure.
Example of Code with Dynamic Id:
#5: Use a single Trigger on the object
Combine all possible triggers on a specific object into just one Trigger. Instead of coding your logic directly inside a trigger, you code it separately in a class. Then in your Trigger, you create an object of the course, then run your records through its logic.
#6: Querying objects having more than 50,000 records.
The total number of records fetched by SOQL query is 50,000 records. If we query more than 50,000 records, we exceed the heap limit, and a runtime exception is thrown.
//Runtime Exception will be thrown for following queey if records > 50K
Account[] accts = [SELECT id,name FROM account];
To avoid this, for loop can be used, and SOQL query can be written outside for loop in the
following way.
for(List<Account> acct :[SELECT id, name FROM account WHERE name LIKE 'Test'])?
{
? ? // Write your logic here
}
Published by
Salesforce Consultant at CloudPrism Solutions || Certified Platform Developer I?|| 2x Salesforce Certified|| PICT’19
Post navigation