Apex is a strongly typed, object-oriented programming language that allows developers to execute flow and transaction control statements on Salesforce servers along with calls to the API (Application Programming Interface). Apex syntax looks like Java and acts like database stored procedures. Apex allows developers to add business logic to most system events, including button clicks, related record updates, and Visualforce pages.
When should you use Apex?
Use Apex when you want to:
- Create Web services
- Create email services
- Perform complex validation over multiple objects
- Create complex business processes that workflows do not support
- Create custom transactional logic (occurs over the entire transaction, not a single record or object)
- Attach custom logic to another operation, such as saving a record so it occurs whenever the operation is executed, regardless if it originated in the user interface, Visualforce page, or from SOAP API.
Triggers
Apex can be invoked by using triggers. Apex triggers allow you to perform custom actions before or after changes have been made to a Salesforce record. A trigger is considered Apex code that executes before or after the following types of operations:
- insert
- update
- delete
- merge
- upsert
- undelete
For example, you can have a trigger run before an object’s records are inserted into the database, after a record has been updated, or even after a record is undeleted (restored) from the Recycle Bin. You can define a trigger for standard objects such as an Account, Contact, or Opportunity. Triggers can also be defined for child objects such as a CaseComment and custom objects.
There are two types of triggers:
- Before Triggers are used to update or validate record values before they are saved to the database.
- After Triggers are used to access field values that are set by the system (such as record’s Id or LastModifiedDate field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue. The records that fire after trigger are read-only.
Bulk Triggers
By default, all triggers are bulk triggers and can process multiple records at a time. Best practice is to always process more than one record at a time. Bulk triggers can handle both single record updates and bulk operations such as:
- Data import
- Lightning Platform Bulk API calls
- Mass actions, such as record owner changes and deletes
- Recursive Apex methods and triggers that invoke bulk DML (Data Manipulation Language) statements
Trigger Syntax
To define a trigger, use the following syntax:
- before insert
- before update
- before delete
- after insert
- after update
- after delete
- after undelete
The following code defines a trigger for the before insert and before update events on the Account object:
The code block of a trigger cannot contain the static keyword. Triggers can only contain keywords that pertain to an inner class. You do not have to manually commit any database changes made by a trigger. If your Apex trigger completes successfully, any database changes are automatically committed. If your Apex trigger does not complete successfully, any changes made to the database are rolled back.
Implementation Considerations
You should consider the following when creating a trigger:
- Upsert triggers fire both before and after insert or before and after update triggers as appropriate
- Merge triggers fire both before and after delete for the losing records, and both before and after update triggers for the winning record.
- Triggers that execute after a record has been undeleted only work with specific objects.
- Field history is not recorded until the end of a trigger. You will not see any history for the current transaction if you query field history in a trigger.
- Field history honors the permission of the current user. No change will be recorded is the user does not have permission to directly edit an object or a field.
- Callouts must be made asynchronously from a trigger so that the trigger process is not blocked while waiting for the external service’s response. Use asynchronous Apex such as a future method to make an asynchronous callout.