Best Practices for Apex Trigger in Salesforce

 

1. Follow the One Trigger Per Object Principle

  • Create a single trigger per object to centralize logic and avoid conflicts.
  • Use a handler class to process the logic, separating the trigger's definition from its implementation.

2. Use Context Variables

  • Use context variables like Trigger.isInsert, Trigger.isUpdate, Trigger.isDelete, etc., to identify the context of the trigger execution.
  • This makes your code modular and avoids redundancy.

3. Bulkify Your Code

  • Always assume that triggers will handle multiple records (bulk operations).
  • Use collections like List, Set, or Map instead of working with a single record.

Example:

apex

List<Account> accountsToUpdate = new List<Account>(); for (Account acc : Trigger.new) { if (acc.Industry == 'Technology') { acc.Rating = 'Hot'; accountsToUpdate.add(acc); } } update accountsToUpdate;

4. Avoid SOQL and DML in Loops

  • Perform SOQL (Salesforce Object Query Language) queries and DML (Data Manipulation Language) operations outside loops to avoid hitting governor limits.

Bad Practice:

apex

for (Contact con : Trigger.new) { Account acc = [SELECT Name FROM Account WHERE Id = :con.AccountId]; acc.Description = 'Updated by Trigger'; update acc; }

Good Practice:

apex

Set<Id> accountIds = new Set<Id>(); for (Contact con : Trigger.new) { accountIds.add(con.AccountId); } Map<Id, Account> accountMap = new Map<Id, Account>( [SELECT Id, Name FROM Account WHERE Id IN :accountIds] ); List<Account> accountsToUpdate = new List<Account>(); for (Contact con : Trigger.new) { if (accountMap.containsKey(con.AccountId)) { Account acc = accountMap.get(con.AccountId); acc.Description = 'Updated by Trigger'; accountsToUpdate.add(acc); } } update accountsToUpdate;

5. Handle Exceptions Gracefully

  • Use try-catch blocks to handle exceptions and log errors using custom objects or the System.debug() method.

6. Ensure Trigger Recursion is Controlled

  • Prevent recursive trigger execution by using static variables.

Example:

apex

public class TriggerHandler { public static Boolean isExecuting = false; }

In Trigger:

apex

if (!TriggerHandler.isExecuting) { TriggerHandler.isExecuting = true; // Trigger logic here TriggerHandler.isExecuting = false; }

7. Write Comprehensive Test Classes

  • Achieve 100% code coverage by testing all possible scenarios, including bulk, single, positive, and negative cases.
  • Use Test.startTest() and Test.stopTest() to validate limits and asynchronous behavior.

8. Minimize Hard-Coding

  • Use Custom Settings, Custom Metadata, or Label records instead of hard-coded values.

9. Follow Naming Conventions

  • Use clear and descriptive names for triggers and handler methods (e.g., AccountTrigger and AccountTriggerHandler).

10. Maintain a Trigger Framework

  • Implement a trigger framework to standardize your approach. Popular frameworks include the TDTM (Trigger Handler Framework) and SObject Framework.

Example Structure:

apex

trigger AccountTrigger on Account (before insert, before update) { AccountTriggerHandler handler = new AccountTriggerHandler(); if (Trigger.isBefore) { if (Trigger.isInsert) { handler.beforeInsert(Trigger.new); } else if (Trigger.isUpdate) { handler.beforeUpdate(Trigger.new); } } }

Handler Class Example:

apex

public class AccountTriggerHandler { public void beforeInsert(List<Account> newRecords) { // Logic here } public void beforeUpdate(List<Account> newRecords) { // Logic here } }

11. Test and Optimize Performance

  • Use Salesforce's debug logs to monitor trigger execution and optimize queries, loops, and DML operations for better performance.

Async/Await Concept in Javascript/LWC

  Concept of async and await in JavaScript async and await are used in asynchronous programming in JavaScript. They help us write clean...