Future Method in Apex

Future Apex is used to run processes in a separate thread, at a later time when system resources become available.

You use the @future annotation to identify methods that run asynchronously.

Future methods are typically used for:

  • Callouts to external Web services. If you are making callouts from a trigger or after performing a DML operation, you must use a future or queueable method. A callout in a trigger would hold the database connection open for the lifetime of the callout and that is a “no-no” in a multitenant environment.
  • Operations you want to run in their own thread, when time permits such as some sort of resource-intensive calculation or processing of records.
  • Isolating DML operations on different sObject types to prevent the mixed DML error.

Syntax of Future Method :-


global class futureClass {
@future
public static void myFutureMethod(List recordIds) {
List accounts = [Select Id, Name from Account Where Id IN :recordIds];
// process account records to do something
}
}
  • Future method must be static and return type is void always.
  • Parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types.
  •  Future methods can’t take standard or custom objects as arguments.
  • A common pattern is to pass the method a List of record IDs that you want to process asynchronously.

Note

The reason why objects can’t be passed as arguments to future methods is because the object can change between the time you call the method and the time that it actually executes. Remember, future methods are executed when system resources become available. In this case, the future method may have an old object value when it actually executes, which can cause all sorts of bad things to happen.

  • Future methods are not guaranteed to execute in the same order as they are called.
  • If you need this type of functionality then Queueable Apex might be a better solution.

Callout Using Future

To make a Web service callout to an external service or API, you create an Apex class with a future method that is marked with (callout=true).

public class SMSUtils {
// Call async from triggers, etc, where callouts are not permitted.
@future(callout=true)
public static void sendSMSAsync(String fromNbr, String toNbr, String m) {
String results = sendSMS(fromNbr, toNbr, m);
System.debug(results);
}

// Call from controllers, etc, for immediate processing
public static String sendSMS(String fromNbr, String toNbr, String m) {
// Calling 'send' will result in a callout
String results = SmsMessage.send(fromNbr, toNbr, m);
insert new SMS_Log__c(to__c=toNbr, from__c=fromNbr, msg__c=results);
return results;
}
}

 Test Class for Future Method Class – 

To test future methods, enclose your test code between the startTest and stopTest test methods. The system collects all asynchronous calls made after the startTest. When stopTest is executed, all these collected asynchronous processes are then run synchronously. You can then assert that the asynchronous call operated properly.

Note : Test code cannot actually send callouts to external systems, so you’ll have to ‘mock’ the callout for test coverage.

@isTest
global class SMSCalloutMock implements <strong>HttpCalloutMock</strong> {
global HttpResponse respond(HttpRequest req) {
// Create a fake response
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/json');
res.setBody('{"status":"success"}');
res.setStatusCode(200);
return res;
}
}
@IsTest
private class Test_SMSUtils {

@IsTest
private static void testSendSms() {
<strong>Test.setMock(HttpCalloutMock.class, new SMSCalloutMock());</strong>
Test.startTest();
SMSUtils.sendSMSAsync('111', '222', 'Greetings!');
Test.stopTest();
// runs callout and check results
List logs = [select msg__c from SMS_Log__c];
System.assertEquals(1, logs.size());
System.assertEquals('success', logs[0].msg__c);
}
}

Important Points – 

Future methods are a great tool, but with great power comes great responsibility. Here are some things to keep in mind when using them:

  • Methods with the future annotation must be static methods, and can only return a void type.
  • The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types; future methods can’t take objects as arguments.
  • Future methods won’t necessarily execute in the same order they are called. In addition, it’s possible that two future methods could run concurrently, which could result in record locking if the two methods were updating the same record.
  • Future methods can’t be used in Visualforce controllers  in  getMethodName(),   setMethodName(), nor in the constructor.
  • You can’t call a future method from a future method. Nor can you invoke a trigger that calls a future method while running a future method.
  • The getContent() and getContentAsPDF() methods can’t be used in methods with the future annotation.
  • You’re limited to 50 future calls per Apex invocation, and there’s an additional limit on the number of calls in a 24-hour period. For more information on limits, see the link below.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s