Salesforce provides one of the most popular and powerful CRM services available on the cloud. Most customers can use Salesforce as is with its default configurations; however there are certain use cases where you need to customize the development to achieve additional workflow or configuration. Take an example such as when you are creating a web or email service. If you want to develop a complex process with additional workflow or a complex validation system for objects, you need to customize your code.
Suppose you are making your own mobile or web-based application, and you want to integrate your application with Salesforce. One of the key requirements to achieving this is to get data from Salesforce on every Salesforce record update. But how do you trigger Salesforce so that it sends you data on every change? Apex Trigger is a handy solution to get this done.
Apex is a multitenant language provided by Salesforce to write backend code whenever you want to create your own custom business application. You can write Apex Code in both triggers and classes, and it can be initiated by triggers on the objects or web-service requests.
There are certain rules and best practices for writing Apex Code in Salesforce as a backend developer. It’s good to follow these guidelines in order to make your system both scalable and manageable. One more important aspect that any organization needs to think about is Test Coverage. When releasing Salesforce Apex Triggers, you can plan proper backup and testing before release of the application.
Our goal is to highlight how to write code that is reusable and suitable for different Salesforce instances. Below you will find several best practices when writing Apex Code that should be implemented to avoid breaking any limitation of the Salesforce platform.
Handling Bulk Data & Other Considerations in Apex Trigger
Many times it happens that we load bulk data of a particular object into the Salesforce system from an external system or source (like through an Excel file). If there is any trigger written on the object for which data is being loaded, the code of that trigger should be so that it is able to handle that bulk data, not just a particular record (unless it’s really needed).
For this, we need to use Trigger.New and Trigger.Old to get a list of records in trigger. To get a map of records, Trigger.NewMap and Trigger.OldMap can be used. And if we are using any DML operation inside trigger, we should use Database.Insert or Database.Update to be able to control transaction rollback.
- Use only one trigger per object principle.
- Minimize the use of SOQL query and DML operations.
- Avoid trigger recursion via a static variable when performing an update on the same object from the trigger.
The reason behind the principle of only one trigger per object is mainly due to the fact that in Salesforce we don’t have any way to guarantee order of execution for triggers on the same object. Having only one trigger gives us the power to control flow of execution, which in turn allows for easy management.
Avoid Salesforce Governor Limits
It’s important to write code in such a way that it does not hit any governor limits as well. This means avoiding SOQL queries, DML operations, and asynchronous calls inside loops. If you are dealing with a large dataset, you can use the limit keyword in SOQL. With large data, you then also have to perform a DML operation on a collection (list) instead of a separate DML for each record. Storage for large data entails using collection variables like Set, Map, and List, and you have to make sure to iterate over this collection.
Lastly, in Apex class try to use minimum getter/setter variables to avoid a view state error on the Visualforce page.=
Processing a Synchronous and Asynchronous Transaction to Avoid Governor Limits
As Apex is executed in a multitenant environment, Salesforce enforces certain Governor limits to avoid the execution of Apex Code consuming a huge number of resources. This will ensure that Apex Code does not take advantage of multitenancy and does not monopolize shared resources. In Apex you can perform both synchronous and asynchronous transactions. So, you have to write code in such a way that it will not hit any governor limits.
This means you have to use a future method, batch class, or queueable class for situations when you need the transaction to be asynchronous. This is due to the fact that for quite a few cases the total limit includes both synchronous and asynchronous transactions.
Use of Interface, Inheritance Class in Apex
Inheritance is a concept of Object Oriented Programming System (OOPS) that helps to inherit/extend properties of a class into the inheriting class. Inheritance, being one of the fundamental concepts of OOPS, helps in Salesforce to keep the common logic in one class; extended classes then get that logic without any need for individual implementation.
For the abstract layer of Apex Code, you should use interface and/or abstract class.
- An interface is used for defining the basic structure (signature) of a method.
- An abstract class is used to separate out common code (methods and/or properties).
You can consider using either an interface or an abstract class during the design phase. They both allow you to separate out common code in order to make it reusable and manageable.