
Salesforce Apex Annotations

Table of Contents
- @AuraEnabled
- @TestSetup
- @isTest
- @Deprecated
- @Future
- @InvocableMethod
- @ReadOnly
- RESTful Service Annotations
- Benefits
- FAQs
Salesforce annotations are crucial in customizing the behavior of Apex code. They offer a streamlined way to provide metadata, enhance functionality, and clarify the purpose of code blocks.
Below is a detailed look at various types of annotations in Salesforce, accompanied by practical examples.
1. @AuraEnabled
The @AuraEnabled
annotation in Salesforce is used to expose Apex methods as Aura-enabled methods, allowing them to be called from Lightning components. Methods annotated with @AuraEnabled
can be invoked from client-side JavaScript controllers in Lightning components to perform server-side actions, such as querying records or updating data. This annotation helps facilitate communication between the client and server in Lightning components, enabling developers to create interactive and dynamic user interfaces in Salesforce Lightning Experience and Salesforce Mobile App.
Learn the intricacies of the @AuraEnabled Annotation and how it enhances your Lightning components.
Example:
public with sharing class AccountController {
@AuraEnabled
public static List<Account> getAccounts() {
return [SELECT Id, Name, Industry FROM Account LIMIT 5];
}
@AuraEnabled
public static void updateAccountName(String accountId, String newName) {
Account acc = [SELECT Id, Name FROM Account WHERE Id = :accountId];
acc.Name = newName;
update acc;
}
}
Looking to ace Salesforce job interviews? These Utimate Salesforce Interview Questions will guide you to success!
In this example, AccountController
is a Apex class that contains two methods annotated with @AuraEnabled
. The getAccounts
method queries the first 5 accounts from the database and returns them as a list. This method can be called from a Lightning component to retrieve account data.
Want to automate your Salesforce processes seamlessly? Understanding triggers in Salesforce to master this essential skill.
The updateAccountName
method takes two parameters, accountId
and newName
, and updates the name of the account with the specified accountId
to the newName
. This method can be called from a Lightning component to update account names.
The @AuraEnabled
annotation is used to expose these methods to the client-side JavaScript controller in a Lightning component, allowing them to be called asynchronously.
CRS Info Solutions offers real-time Salesforce course for beginners designed to equip learners with practical knowledge and industry skills in Salesforce. Enroll for demo today.
2. @TestSetup
The @TestSetup
annotation in Salesforce is used to define a method that sets up test data that is shared across all test methods in a test class. This annotation is particularly useful for creating common test data that needs to be used in multiple test methods, reducing duplication and ensuring consistency in test execution. Test setup methods annotated with @TestSetup
are executed before each test method in the test class, providing a clean and consistent environment for testing.
Read more about custom page layouts in Salesforce.
Example:
@isTest
private class TestSetupExample {
@TestSetup
static void setupTestData() {
// Create test records
List<Account> accounts = new List<Account>();
for(Integer i=0; i<5; i++) {
Account acc = new Account(Name='Test Account ' + i);
accounts.add(acc);
}
insert accounts;
}
@isTest
static void testMethod() {
// Test method that uses the test data created in the setup
List<Account> accs = [SELECT Id, Name FROM Account];
System.assertEquals(5, accs.size());
}
}
In this example, the TestSetupExample
class contains a method called setupTestData
annotated with @TestSetup
. This method is used to create test records, in this case, five Account records with names like “Test Account 0”, “Test Account 1”, etc. The @TestSetup
annotation ensures that the test data is created before any test methods in the test class are executed.
Read more: Approval Process in Salesforce.
The testMethod
method is a test method that queries the Account records created in the setup method and asserts that there are five records. Since the @TestSetup
method has already created the test data, the testMethod
can focus on testing the functionality without having to worry about creating test data within the test method itself.
3. @isTest
The @isTest
annotation in Salesforce is used to define a method as a test method, allowing it to be executed as part of the Apex test framework. Test methods annotated with @isTest
are used to test Apex code and ensure its functionality, helping developers identify and fix issues early in the development process. These methods do not count against Apex code limits and are crucial for maintaining code quality and ensuring the stability of Salesforce applications.
Example:
@isTest
private class TestExample {
@isTest
static void testMethod() {
// Test logic
Integer a = 1;
Integer b = 2;
Integer result = a + b;
System.assertEquals(3, result, 'Sum should be 3');
}
}
In this example, the TestExample
class contains a method called testMethod
annotated with @isTest
. This method is a test method that contains the logic to be tested. In this case, it adds two integers a
and b
and asserts that the result is equal to 3 using the System.assertEquals
method.
The @isTest
annotation indicates that the testMethod
is a test method and should be executed as part of the Salesforce test framework. Test methods annotated with @isTest
don’t count against the organization’s Apex code limit and are used to verify that your code works as expected.
Read more: Types of relationships in Salesforce
4. @Deprecated
The @Deprecated
annotation in Salesforce is used to indicate that a method or class is no longer recommended for use and may be removed in future versions. It serves as a warning to developers that the functionality should be avoided in favor of newer, more efficient alternatives. While the deprecated code will still function, Salesforce recommends updating to the recommended approach to ensure compatibility with future releases and to take advantage of improvements and best practices.
Example:
public class DeprecatedExample {
// This method is deprecated and should not be used
@Deprecated
public static void oldMethod() {
System.debug('This method is deprecated');
}
public static void newMethod() {
System.debug('This is the new method');
}
}
In this example, the oldMethod
is marked as deprecated using the @Deprecated
annotation. This indicates to developers that the method should no longer be used and may be removed in the future. The newMethod
is a new method that should be used instead of oldMethod
.
Using the @Deprecated
annotation helps to communicate to other developers that a method is no longer recommended for use, allowing them to update their code accordingly.
Read more: What are Page layouts in Salesforce and how to create Page layouts?
5. @Future
The @Future
annotation in Salesforce is used to designate a method as a future method, allowing it to be executed asynchronously at a later time. This annotation is typically used when a method needs to perform long-running operations, such as callouts to external systems or batch processing, without blocking the main thread. Future methods are queued and executed by the Salesforce platform, providing a way to offload intensive tasks and improve application performance.
Example:
public class FutureExample {
@Future
public static void myFutureMethod(String name) {
System.debug('Hello, ' + name + '! This is executed asynchronously.');
}
public static void mainMethod() {
// Call the future method
myFutureMethod('John');
System.debug('Main method continues to execute while the future method runs in the background.');
}
}
In this example, the myFutureMethod
is annotated with @Future
, indicating that it should be executed asynchronously in the background. When the mainMethod
is called, it invokes myFutureMethod
with the name ‘John’. The mainMethod
continues to execute while myFutureMethod
runs in the background, allowing for parallel execution of code.
The @Future
annotation is commonly used for long-running operations, such as making callouts to external systems or performing complex calculations, that would otherwise block the user interface. By using @Future
, you can offload these operations to run asynchronously, improving the performance and responsiveness of your Salesforce application.
Read more about formula fields in Salesforce. This tutorial covers everything you need to know to master formula fields and enhance your Salesforce expertise.
6. @InvocableMethod
The @InvocableMethod
annotation in Salesforce is used to define a method as an invocable method that can be called by external systems, such as Process Builder or Flow. This annotation allows the method to be exposed as an action that can be executed when certain conditions are met. It is commonly used in Salesforce to create custom actions that can be triggered from declarative tools, providing flexibility and customization options without the need for complex coding.
Example:
public class InvocableMethodExample {
@InvocableMethod(label='Convert Leads')
public static void convertLeads(List<Id> leadIds) {
// Your logic to convert leads
List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>();
for(Id leadId : leadIds) {
Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(leadId);
lc.setConvertedStatus('Qualified');
leadConverts.add(lc);
}
List<Database.LeadConvertResult> results = Database.convertLead(leadConverts);
}
}
In this example, the InvocableMethodExample
class contains a method called convertLeads
annotated with @InvocableMethod
. This annotation marks the method as an invocable method that can be called from a Flow or Process Builder.
The convertLeads
method takes a list of Lead record IDs as a parameter and converts these leads into contacts, accounts, and opportunities. This method can be used in a Flow or Process Builder to automate the lead conversion process.
The label
attribute of the @InvocableMethod
annotation specifies the label that will be displayed in the Flow or Process Builder when selecting this method. This makes it easier for admins to understand the purpose of the method and how it should be used in their automation processes.
Read more: Strings in Salesforce Apex
7. @ReadOnly
The @ReadOnly
annotation in Salesforce is used to ensure that a method or class is read-only, meaning it cannot perform any DML (Data Manipulation Language) operations such as insert, update, or delete on records. This annotation is often used in situations where data should not be modified, such as in triggers that are only meant for querying records or in batch classes where the goal is to process large volumes of data without changing it.
Example:
public class ReadOnlyExample {
@ReadOnly
public static void readOnlyMethod() {
// Query some data
List<Account> accounts = [SELECT Id, Name FROM Account LIMIT 10];
for(Account acc : accounts) {
System.debug('Account Name: ' + acc.Name);
}
}
public static void mainMethod() {
// Call the read-only method
readOnlyMethod();
System.debug('Main method continues to execute');
}
}
In this example, the readOnlyMethod
is annotated with @ReadOnly
, indicating that it should not perform any DML (Data Manipulation Language) operations, such as insert, update, or delete, on records. The method queries a list of Account records and prints their names to the debug log.
The mainMethod
is a regular method that calls readOnlyMethod
. Since readOnlyMethod
is marked as read-only, it can be called from mainMethod
without any restrictions. The read-only behavior ensures that the data queried in readOnlyMethod
cannot be modified, providing a safe way to retrieve data without the risk of unintentional changes.
Read more: Loops in Salesforce Apex
8. RESTful Service Annotations
Description: These annotations define methods in Apex classes as RESTful services, enabling them to handle respective HTTP requests.
@HttpDelete
The @HttpDelete
annotation in Salesforce is used to define an Apex method as an HTTP DELETE request handler. This annotation allows the method to be invoked by external systems using the DELETE HTTP method, typically used for deleting resources. Methods annotated with @HttpDelete
must be in a class annotated with @RestResource
and can accept parameters from the request.
@RestResource(urlMapping='/exampleEndpoint/*')
global with sharing class ExampleRestResource {
@HttpDelete
global static void doDelete() {
// Your logic to delete a record
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
String recordId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
delete [SELECT Id FROM CustomObject__c WHERE Id = :recordId];
res.statusCode = 204; // HTTP 204 No Content
res.responseBody = Blob.valueOf('Record deleted successfully');
}
}
In this example, the doDelete
method is annotated with @HttpDelete
and is responsible for deleting a record of the CustomObject__c object based on the ID provided in the request URI. The method sets the HTTP response status code to 204 (No Content) and provides a response body indicating the successful deletion of the record.
@HttpGet
The @HttpGet
annotation in Salesforce is used to define an Apex method as an HTTP GET request handler. This annotation allows the method to be invoked by external systems using the GET HTTP method, typically used for retrieving resources. Methods annotated with @HttpGet
must be in a class annotated with @RestResource
and can accept parameters from the request.
@RestResource(urlMapping='/exampleEndpoint/*')
global with sharing class ExampleRestResource {
@HttpGet
global static void doGet() {
// Your logic to retrieve data
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
String recordId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
CustomObject__c obj = [SELECT Id, Name FROM CustomObject__c WHERE Id = :recordId];
res.statusCode = 200; // HTTP 200 OK
res.responseBody = Blob.valueOf(JSON.serialize(obj));
}
}
In this example, the doGet
method is annotated with @HttpGet
and is responsible for retrieving a record of the CustomObject__c object based on the ID provided in the request URI. The method sets the HTTP response status code to 200 (OK) and provides a response body containing the JSON representation of the retrieved object.
Understand the importance of Record Types in Salesforce and how they can help manage different business processes with ease.
@HttpPatch
The @HttpPatch
annotation in Salesforce is used to define an Apex method as an HTTP PATCH request handler. This annotation allows the method to be invoked by external systems using the PATCH HTTP method, typically used for partial updates to resources. Methods annotated with @HttpPatch
must be in a class annotated with @RestResource
and can accept parameters from the request.
@RestResource(urlMapping='/exampleEndpoint/*')
global with sharing class ExampleRestResource {
@HttpPatch
global static void doPatch(String requestBody) {
// Your logic to update a record
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
String recordId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
CustomObject__c obj = [SELECT Id, Name FROM CustomObject__c WHERE Id = :recordId];
obj.Name = 'Updated Name';
update obj;
res.statusCode = 200; // HTTP 200 OK
res.responseBody = Blob.valueOf('Record updated successfully');
}
}
In this example, the doPatch
method is annotated with @HttpPatch
and is responsible for updating a record of the CustomObject__c object based on the ID provided in the request URI. The method sets the HTTP response status code to 200 (OK) and provides a response body indicating the successful update of the record.
Dive into Arrays in Salesforce Apex to handle collections of data efficiently in your Apex code.”
@HttpPost
The @HttpPost
annotation in Salesforce is used to define an Apex method as an HTTP POST request handler. This annotation allows the method to be invoked by external systems using the POST HTTP method, typically used for creating new resources. Methods annotated with @HttpPost
must be in a class annotated with @RestResource
and can accept parameters from the request.
@RestResource(urlMapping='/exampleEndpoint')
global with sharing class ExampleRestResource {
@HttpPost
global static void doPost(String requestBody) {
// Your logic to create a new record
RestResponse res = RestContext.response;
CustomObject__c obj = new CustomObject__c(Name='New Record');
insert obj;
res.statusCode = 201; // HTTP 201 Created
res.responseBody = Blob.valueOf('Record created successfully');
}
}
In this example, the doPost
method is annotated with @HttpPost
and is responsible for creating a new record of the CustomObject__c object. The method sets the HTTP response status code to 201 (Created) and provides a response body indicating the successful creation of the record.
@HttpPut
The @HttpPut
annotation in Salesforce is used to define an Apex method as an HTTP PUT request handler. This annotation allows the method to be invoked by external systems using the PUT HTTP method, typically used for updating existing resources. Methods annotated with @HttpPut
must be in a class annotated with @RestResource
and can accept parameters from the request.
@RestResource(urlMapping='/exampleEndpoint/*')
global with sharing class ExampleRestResource {
@HttpPut
global static void doPut(String requestBody) {
// Your logic to update a record
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
String recordId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
CustomObject__c obj = [SELECT Id, Name FROM CustomObject__c WHERE Id = :recordId];
obj.Name = 'Updated Name';
update obj;
res.statusCode = 200; // HTTP 200 OK
res.responseBody = Blob.valueOf('Record updated successfully');
}
}
In this example, the doPut
method is annotated with @HttpPut
and is responsible for updating a record of the CustomObject__c object based on the ID provided in the request URI. The method sets the HTTP response status code to 200 (OK) and provides a response body indicating the successful update of the record.
Top 10 interviews questions on Salesforce Annotations with coding examples.
Benefits of Using Annotations in Salesforce: Scenarios and Advantages
- Enhanced Code Efficiency: Annotations like
@Future
and@ReadOnly
allow developers to implement complex functionalities like asynchronous processing and handling large data sets efficiently.
Scenario: Using@Future
to offload heavy data processing tasks, ensuring the main thread remains responsive for user interactions. - Improved Code Organization and Maintenance: Annotations like
@isTest
and@Deprecated
assist in keeping the codebase organized by clearly differentiating test code from production code and phasing out obsolete methods.
Scenario: Marking legacy methods with@Deprecated
to warn developers against their use in new implementations. - Increased Readability and Clarity: Annotations provide a clear understanding of the code’s purpose at a glance, enhancing the readability for other developers.
Scenario: Utilizing@AuraEnabled
to immediately signify the interaction between Apex and Lightning Components. - Streamlined Testing and Debugging: With
@TestSetup
, creating test data becomes more efficient, and@isTest
ensures test codes are isolated from production codes, simplifying testing and debugging processes.
Scenario: Using@TestSetup
to create a shared testing environment, reducing redundancy in test data creation. - Integration with Salesforce Ecosystem: Annotations like
@InvocableMethod
enable seamless integration of custom Apex logic with Salesforce’s declarative tools like Process Builder and Flow.
Scenario: Creating an@InvocableMethod
that can be triggered by a Process Builder to perform custom actions based on certain criteria.
Salesforce annotations are powerful tools that not only enhance the capabilities of Apex code but also contribute to a more organized, efficient, and understandable codebase. Understanding and leveraging these annotations is key to developing advanced and maintainable Salesforce applications.
Read more: DML in Salesforce Apex
Frequently Asked Questions
1. Why do we use @future annotation in Salesforce?
The @future
annotation in Salesforce is used to denote methods that should be executed asynchronously in the background, separate from the main thread. This is particularly useful for long-running operations, such as making callouts to external services or performing complex calculations, that could otherwise block the user interface and lead to a poor user experience. By marking a method with @future
, Salesforce queues the method for execution and allows the current transaction to continue without waiting for the asynchronous method to complete.
Read more: SOQL Query in Salesforce
Another key reason for using @future
is to avoid hitting Salesforce’s governor limits, such as the maximum CPU time or heap size. Asynchronous processing with @future
allows for more efficient resource management, as the queued method runs in its own context and has its own set of governor limits. This helps prevent issues such as governor limit exceptions that could occur if the operation were performed synchronously within the main transaction.
Additionally, the @future
annotation is often used to perform batch processing, where large volumes of records need to be processed in chunks. By breaking up the work into smaller batches and executing them asynchronously, developers can avoid hitting limits and ensure that the overall process is efficient and scalable. Overall, the @future
annotation is a powerful tool in Salesforce development for managing long-running operations, avoiding governor limits, and improving the performance of applications.
Read more: Array methods in Salesforce Apex
2. When should the @ReadOnly
annotation be used, and what are its limitations?
The @ReadOnly
annotation in Salesforce should be used when you want to ensure that a method or class does not perform any DML (Data Manipulation Language) operations, such as insert, update, or delete, on records. It is commonly used in scenarios where you only need to read data from Salesforce and want to prevent accidental modification of records.
However, it’s important to note that the @ReadOnly
annotation has limitations. It does not prevent the modification of static variables or static methods that perform DML operations. Additionally, it does not enforce read-only behavior for related objects, such as parent or child records, so care must be taken to ensure that all related records are treated as read-only if necessary.
Checkout: DML statements in Salesforce
3. What are the best practices for using the @AuraEnabled annotation in Lightning components?
When using the @AuraEnabled
annotation in Lightning components, several best practices should be followed to ensure efficient and secure development. Firstly, only use @AuraEnabled
on methods that are intended to be called from the client-side JavaScript controller. This helps prevent unnecessary exposure of server-side logic.
Secondly, use @AuraEnabled(cacheable=true)
for methods that retrieve data from Salesforce and don’t require real-time updates. This allows the Lightning framework to cache the data for improved performance and reduced server load.
Lastly, always validate input parameters to @AuraEnabled
methods to prevent injection attacks and ensure data integrity. Following these best practices helps ensure that your Lightning components are secure, performant, and maintainable.
Read more: Salesforce apex programming examples
4. How does the @InvocableMethod annotation differ from other Apex annotations, and when should it be used?
The @InvocableMethod
annotation in Salesforce Apex is unique compared to other annotations because it allows you to define methods that can be invoked by external processes, such as Process Builder and Flow. Unlike annotations like @AuraEnabled
or @HttpPost
, which are primarily used for client-server communication, @InvocableMethod
is used for server-server or server-external system communication.
@InvocableMethod
should be used when you want to expose an Apex method as an action that can be executed by declarative tools like Process Builder or Flow. This is useful for automating complex business processes that require custom logic or integration with external systems. @InvocableMethod
allows you to encapsulate this logic in a reusable Apex method that can be easily called from various places in your Salesforce org.
Collection is one of the important concept, checkout: Collections in Salesforce Apex
5. What considerations should be taken into account when using the @Http annotations in Apex REST services?
When using the @Http
annotations in Apex REST services, several considerations should be taken into account to ensure secure and efficient implementation. First and foremost, always validate incoming requests to prevent injection attacks and ensure data integrity. Additionally, use the appropriate @Http
annotation (@HttpGet
, @HttpPost
, @HttpPut
, @HttpDelete
, @HttpPatch
) based on the HTTP method being used and the purpose of the method.
It’s also important to handle exceptions gracefully and return meaningful error messages to the client. This helps improve the usability of your REST services and provides helpful feedback to consumers. Lastly, consider implementing rate limiting and authentication mechanisms to protect your REST services from abuse and unauthorized access.
Read more: Arrays in Salesforce Apex