You are on page 1of 140

What is Apex?

• Apex is Salesforce's proprietary programming language,


designed for customizing and extending the functionality
of the Salesforce platform.
• It allows developers to create tailored business logic,
automate processes, and build custom applications to meet
specific organizational requirements.
• As a server-side language, Apex executes directly on the
Salesforce servers, facilitating seamless integration with the
platform's data and services.
How Does Apex Work?

The developers user create custom logic using Apex code, triggers, or Flows to address specific business
requirements. The developed code undergoes validation through the Apex compiler, which checks for
syntax errors and issues. If errors are detected, the compiler generates messages, initiating communication
via the application server back to the developer for necessary corrections. Once the code is error-free, the
application server transforms it into metadata, storing it in the Salesforce organization's data storage. The end
user is then prompted with a request containing the prepared Apex code, and upon triggering its execution,
the result is returned, marking the completion of the development, validation, and deployment cycle. It's
important to note that this description offers a simplified overview, and variations may exist based on
specific Salesforce development requirements.
Salesforce Application Anatomy
Data Type in Apex
Data Type Description Sample Value
Blob Represents a binary large object (raw binary data) Blob myBlob = Blob.valueOf('Hello, Salesforce!');

Boolean Represents true or false values Boolean isTrue = true;

Date Represents a specific date without a time component Date myDate = Date.today();

Datetime Represents a specific date and time Datetime myDatetime = Datetime.now();

Decimal Represents numbers with decimal points Decimal myDecimal = 3.14;


ID Represents a Salesforce record ID Id recordId = '001R00000123ABC';
Integer Represents whole numbers Integer myNumber = 42;

String Represents a sequence of characters String myString = 'Hello, Salesforce!';

Account myAccount = new Account(Name = 'ABC


SObject Represents Salesforce objects
Corp');

Long Represents a 64-bit integer Long myLong = 1234567890123456;

The data types used in Apex for coding purposes may differ from the data types used when creating
fields or records in Salesforce.
Variable in Apex
Integer inValue = 27;

System.debug('ID :' + inValue);

In Apex, a variable is a named memory location associated with a specific data type, used to store and
manage information during program execution.

 Explanation:
• This code sets up an Integer variable named inValue and assigns it the value 27. The
subsequent debug statement prints the string 'ID :' along with the value stored in the
inValue variable to the debug log. In this case, it would output something like 'ID : 27' in
the debug log.

 Debug Log Output:


• When you run this code, the debug log will capture the output, providing information
about the state of the variables and the execution flow.
Operators
Operators in Apex are symbols that perform operations on variables and values; they include arithmetic (+, -, *, /),
relational (==, !=, <, >), logical (&&, ||, !), and assignment (=) operators, among others.

Operator Description Example


+ Addition: Adds two values. Integer sum = 5 + 3; // Result: 8

- Subtraction: Subtracts the right operand from the left. Decimal difference = 10.5 - 3.2; // Result: 7.3

* Multiplication: Multiplies two values. Integer product = 4 * 6; // Result: 24

/ Division: Divides the left operand by the right. Decimal quotient = 15.0 / 3.0; // Result: 5.0

% Modulus: Returns the remainder of the division. Integer remainder = 17 % 5; // Result: 2

++ Increment: Increases the value of a variable by 1. Integer num = 5; num++; // Result: 6

-- Decrement: Decreases the value of a variable by 1. Integer num = 8; num--; // Result: 7

= Assignment: Assigns a value to a variable. String name = 'John';

== Equality: Compares if two values are equal. Boolean isEqual = (a == b);

!= Inequality: Compares if two values are not equal. Boolean notEqual = (a != b);
Collection
1. List: A List in Apex is an ordered collection of elements, allowing
duplicates, and accessed by an index.

2. Set: A Set in Apex is an unordered collection of unique elements,


ensuring each element appears only once.

3. Map: A Map in Apex is a collection of key-value pairs, where each


key must be unique, providing a way to associate values with unique
identifiers
Using Collection in Apex (list)
List<Integer> listOfNumbers = new List <Integer> ();
listOfNumbers.add(1);
listOfNumbers.add(3);
listOfNumbers.add(3);
System.debug('listOfNumbers: ' + listOfNumbers);

 Explanation:
The code creates a List of Integer values named listOfNumbers and adds the numbers 1,3 and
3 to the list. Lists in Apex allow duplicate elements, so having two occurrences of the
value 3 is allowed.

 Debug Log Output:


When this code is executed, the debug log will display the content of the listOfNumbers,
including all the added values: listOfNumbers: (1, 3, 3).
Using Collection in Apex (set)
Set<Integer> setOfNumbers = new Set<Integer>();
setOfNumbers.add(3);
setOfNumbers.add(2);
setOfNumbers.add(2);
System.debug('setOfNumbers: ' + setOfNumbers);

 Explanation:
The code creates a Set of Integer values named setOfNumbers and adds the numbers 3,
2 and 2 to the set. Sets in Apex do not allow duplicate elements, so the second
occurrence of the value 2 is ignored.

 Debug Log Output:


When this code is executed, the debug log will display the content of the
setOfNumbers, including only the unique values: setOfNumbers: ( 3,2).
Using Collection in Apex (map)
Map<Integer, String> mapOfIntegerString = new Map<Integer, String>();
mapOfIntegerString.put(1, 'one');
mapOfIntegerString.put(2, 'two');
mapOfIntegerString.put(3, 'three');
mapOfIntegerString.put(3, 'four');
System.debug('mapOfIntegerString: ' + mapOfIntegerString);
System.debug('Value at 3: ' + mapOfIntegerString.get(3));

 Explanation: The code creates a Map associating Integer keys with String
values named mapOfIntegerString and adds key-value pairs to it. It then
outputs the content of the map and retrieves the value associated with the
key 3.

 Debug Log Output:When this code is executed, the debug log will display
the content of the mapOfIntegerString map and the value associated with
the key 3.
•mapOfIntegerString: {1=one, 2=two, 3=four}
•Value at 3: four
Using Loops
 List Initialization: List<Integer> listOfNumbers = new
List<Integer>();: Declares a new list named listOfNumbers
that can hold Integer values.
//using loop
 Maximum List Size: Integer maxListSize = 5;: Initializes a List<Integer> listOfNumbers = new List<Integer>();
Integer maxListSize = 5;
variable maxListSize with the value 5, indicating the desired
for (Integer i = 1; i <= maxListSize; i++) {
size of the list. listOfNumbers.add(i);
}
 For Loop: for(Integer i = 1; i <= maxListSize; i++) {: System.debug('listOfNumbers: ' + listOfNumbers);
A for loop that iterates from 1 to the specified maxListSize (5)
and adds each integer to the list.

 List Population: listOfNumbers.add(i);: Adds each integer i to listOfNumbers: (1, 2, 3, 4, 5)


the listOfNumbers during each iteration of the loop.

 Debug Statement: System.debug('listOfNumbers: ' +


listOfNumbers);: Outputs a debug statement to the system
log, displaying the content of the populated listOfNumbers.
If Else Statement
Integer myNumber = 10;

if (myNumber > 5) {
System.debug('The number is greater than 5.');
} else {
System.debug('The number is not greater than 5.');
}

• The condition myNumber > 5 is evaluated.


• If the condition is true, the code block inside the first set of curly braces {}
is executed.
• If the condition is false, the code block inside the second set of curly
braces {} (after the "else" keyword) is executed.

myNumber is 10  The number is greater than 5.


myNumber is 3  The number is not greater than 5
Switch Statement
• The variable num represents the number to be evaluated.
• The switch on statement is used to evaluate the value of
Integer num = 5;
num. String result;
• Different cases are defined using when, and each case
includes a set of values. switch on num {
• The when else statement is similar to the default case and is when 1, 3, 5, 7, 9 {
result = 'Odd';
executed if none of the previous cases match. }
when 2, 4, 6, 8, 10 {
result = 'Even';
Num is 5  result : odd }
when else {
Num is 8  result : even
result = 'Invalid number';
Num is 12  invalid number }
}

System.debug('Result: ' + result);


Assignmemt 1

Write a apex program to store all the number in a list starting from 1 until 20.
Only numbers stored at even positions in the list should be added to get their sum
which should be output to the debug log.
(Hint: use a while loop and if else along with system.debug())
Solution 1
Integer sum = 0;
List<Integer> listEven = new List<Integer>();

// the list with numbers from 1 to 20


for (Integer i = 1; i <= 20; i++) {
listEven.add(i);
}

// Calculate the sum of numbers at even positions in the list


for (Integer i = 0; i < listEven.size(); i++) {
if (Math.mod(i, 2) == 0) {
sum = sum + listEven[i];
}
}

// Output the result


System.debug(sum);
Introduction to Class, Method, Static and OOPs
Concept in Apex
1- Class Definition:

public class MyClass {


// Class body
}

• A class in Apex is a blueprint for creating objects


.
• It defines a new data type and encapsulates data and behavior.

• It is a user-defined data type.


2- Constructor:

public class MyClass {


public MyClass() {
// Constructor body
}
}

• In Apex, constructors are similar to other languages and are used to initialize object
instances.

• The constructor method has the same name as the class and is executed when an object is
created.
3- State (Member Variables)::

public class MyClass {


public String attribute1;
private Integer attribute2;

public MyClass(String param1, Integer param2) {


this.attribute1 = param1;
this.attribute2 = param2;
}
}

• State in Apex refers to the properties or attributes that define the object.

• Member variables hold the state of an object and are declared within the class.
4- Behavior (Member Functions/Methods):

public class MyClass {


public String attribute1;

public MyClass(String param1) {


this.attribute1 = param1;
}
public void performAction() {
// Method body
System.debug('Performing an action.');
}
}

• Behavior in Apex refers to the actions or operations that an object can perform
.
• Member functions or methods are defined within the class and are used to define the
behavior.
public | private | global
Public Private global
If you declare a class as public then it If you declare a class as private If you declare a class as global
will be visible to other classes in the then it will not be visible to then it is globally available across
same namespace. Any other class can other classes. all namespaces.
call or refer to any public classes in the You can only declare Test Consider it as a global citizen
same namespace. Classes and inner classes as who can travel freely across all
private. the namespaces without any
Any other top-level class can not passport.
be declared as private.

What is namespace?
You can consider namespace as a package or folder in which all your classes will be
present. There is a default namespace present when you have not declared or used any
other namespaces
Finaly the summary of access modifiers for class members in Apex:

1- Global: Members can be accessed across all classes within different namespaces. Typically used
for exposing elements in managed packages.

2- Public: Members can be accessed across all classes within the same namespace. This is the
default access level if none is specified.

3- Protected: Members can be accessed by inner classes or child classes within the same
namespace.

4- Private: Members cannot be accessed from other classes. This is the default access level,
ensuring a high level of encapsulation within the same class.
[virtual | abstract | with sharing | without sharing | (none) ]

Name Definition

virtual If you declare a class as virtual it implies that this class can be extended
and can be used as a parent class.

abstract If you declare a class as abstract it implies that the class has abstract
methods and the child class which is going to extend this abstract class
has to implement the abstract methods.
Name Definition
without sharing • If you declare a class as without sharing then the class will run in system mode.
• When a class is declared with the without sharing keyword, it disregards the sharing
rules and provides access to all records in the system.
• The visibility of records is not restricted by the user's permissions, role hierarchy, or
sharing settings.
• It is used when developers need to perform operations without considering the
sharing rules.
with sharing • If you declare a class as with sharing it implies that the class should run in user
mode rather than system mode.
• When a class is declared with the with sharing keyword, it enforces the sharing rules
of the current user executing the code.
• The visibility and access to records are determined by the user's permissions, role
hierarchy, and sharing settings.
• This is the default behavior if the with or without keywords are not specified.
Note:

• It's important to use these keywords thoughtfully, considering the security implications of your code.
In general, it's recommended to use with sharing to respect the sharing settings and ensure a more
secure application.
• The sharing setting only affects queries to the database. DML (Data Manipulation Language)
operations like inserts and updates always respect the organization's sharing rules, regardless of the
class's sharing setting.

public with sharing class AccountController {


public List<Account> getMyAccounts() { In the AccountController class, the with
return [SELECT Id, Name FROM Account sharing keyword ensures that only the
WHERE OwnerId =:User.getUserId()]; records owned by the current user are
} retrieved.
} In contrast, the AllAccountsController
class, declared as without sharing, retrieves
public without sharing class AllAccountsController {
all records, irrespective of ownership or
public List<Account> getAllAccounts() {
return [SELECT Id, Name FROM Account];
sharing settings.
}
}
An Object is an instance of a class, that is, a class in action.
You create custom objects to represent and store data. These objects are instances of
predefined classes provided by the Salesforce platform.

// Define a custom class (a blueprint)


public class CustomObjectClass {
// Define attributes or properties In this example, CustomObjectClass
public String name; is a class definition with attributes
public Integer quantity; (name and quantity) and a method
(displayInfo).
// Define methods or behaviors myObject is an instance of this class,
public void displayInfo() { representing a specific object with its
System.debug('Name: ' + name + ', Quantity: ' + quantity); own data and behavior.
}
}

// Create an instance of the class (an object)


CustomObjectClass myObject = new CustomObjectClass();

// Set values for the object's properties


myObject.name = 'Sample Object';
myObject.quantity = 10;

// Call a method on the object


myObject.displayInfo();
Static Vs Instance
Differences between "Pass by Value" and "Pass by references"

Pass by Value (Primitive Pass by reference (Complex Types)


Characteristic Types)
Data Types Primitive types ( Integer, Complex types (custom objects, lists, maps)
Boolean)
What is Passed Actual value of the variable Reference (memory address) to the object

Changes Inside Do not affect the original value Changes to the internal state of the object are visible outside
Method outside the method
Example Integer x = 5; CustomObject myObject = new CustomObject('Original’);
modifyInteger(x); modifyObject(myObject);
System.debug(x); System.debug(myObject.name);

// Output: 5 // Output: original object modified


Extending class and Interfaces

 Extending a Class
• Use the virtual keyword
• Mark the method and class as virtual
• Extending class can override and provide a new definition to
the virtual method

 Interfaces
• A contract that enforces what the child must do
• Only contains method declarations not definitions
• Cannot be instantiated on their own
• Recording
Extending class
In Apex, you can create a new class that is an extension of an existing class using the extends keyword. This is
known as class inheritance, where the new class inherits the properties and methods of the existing class.

public class ParentClass {


// Properties and methods of the parent class
}

public class ChildClass extends ParentClass {


// Additional properties and methods of the child class
}

In the example, ChildClass is extending ParentClass. This means that ChildClass inherits all the
properties and methods of ParentClass. You can then add additional functionality, properties, or
methods to the child class.
Extending class

public class Animal {


public String name;

public Animal(String n) {
name = n; In this example, Dog is a subclass of Animal. It
} inherits the name property and the makeSound
method from Animal and adds its own method bark.
public void makeSound() {
System.debug('Animal makes a sound'); You can then create instances of Dog and use both the
} inherited and the new functionalities:
}

public class Dog extends Animal {


public Dog(String n) {
super(n); // Call the constructor of the parent class
}

public void bark() {


System.debug('Dog barks!');
}
}
Extending class
Dog myDog = new Dog('Buddy’);

System.debug('Name: ' + myDog.name);

myDog.makeSound(); // Inherited method

myDog.bark(); // Method specific to Dog class

 System.debug('Name: ' + myDog.name); Outputs the name property of the myDog instance, which is set to 'Buddy' during
instantiation.

 myDog.makeSound(); Calls the makeSound method inherited from the Animal class. The debug statement within the method
prints "Animal makes a sound."

 myDog.bark();: Calls the bark method specific to the Dog class. The debug statement within the method prints "Dog barks!"

USER_DEBUG [1]- DEBUG - Name: Buddy

USER_DEBUG [2 ]- DEBUG - Animal makes a sound

USER_DEBUG [3 ]- DEBUG - Dog barks!


Interfaces
The interfaces provide a way to define a contract for classes, ensuring that implementing classes
adhere to a specific set of methods. An interface is like a blueprint for a class, specifying method
signatures that must be implemented by any class that implements the interface.

Simple exemple of an interface in Apex:

public interface Animal {


void makeSound();
String getName();
}

In this example, the Animal interface has two method signatures:


makeSound and getName. Any class that implements this
interface must provide concrete implementations for these
methods.
Interfaces
Create a class that implements the Animal interface:

The Dog class implements the Animal interface.


It provides concrete implementations for both the
public class Dog implements Animal { makeSound and getName methods defined in the
private String name; Animal interface.
public Dog(String n) {
name = n; You can then use instances of the Dog class as if
} they were instances of the Animal interface:

public void makeSound() {


Animal myDog = new Dog('Buddy’);
System.debug('Dog barks!');
}
myDog.makeSound(); // Outputs: Dog barks!
public String getName() {
System.debug('Name: ' + myDog.getName());
return name;
// Outputs: Name: Buddy
}
}
Assignmemt 2
Write an Apex class MathCalulator that performs arithmetic operations on Integer
based on the following methods on the input numbers passed to them as arguments.

• add() – sum2 input integer arguments and returns the summation


• multiply() – multiplies 2 input integer arguments and returns the product

Add a method printOutput() that prints the summation or the product from the add
or multiple methods to the Debug Log.

(Hint: Implement add() , multiply() and printOutput() as private static methods


invoked by a public instance doMath() method. The doMath() method wil be
invoked from the Execute Anonymous window)
Solution :

public class MathCalculator {


private static integer add ( integer a, integer b ) {
return a+b;
}

private static integer multiply ( integer a, integer b ) {


return a*b;
}

private static integer subtract ( integer a, integer b ) {


return a-b;
}

public MathCalculator() {
}
private static void printOutput ( integer output ) {
system.debug(output);
}
public void doMath ( integer a, integer b, string operator ) {
Integer value = 0;
If ( operator == ‘+’ . ) {
value = add ( a , b );
}
else if ( operator == ‘*’ ) {
value = multiply ( a, b ) ;
}
else if ( operator == ‘-‘ ) {
value = subtract ( a, b ) ;
}
MathCalculator.printOutput ( value ) ;
}
}
Developer Tools & Debugging Tools

1. Developer Console

It’s available in Enterprise, Performance, Unlimited, Developer and Database.com editions.

What you can do using Developer Console?

• Debugging and Troubleshooting


• Editing and navigating Source Code
• Testing and Validating Performance
• Executing Queries (SOQL and SOSL) and etc
Developer Console

In Salesforce Developer Console, various features and tools are available to assist developers
in building and troubleshooting their applications. Here's a brief overview of the terms you
mentioned:

logs • logs refer to debug logs that provide information about the execution of your code.
• You can use debug statements in your Apex code to generate logs and analyze the
flow of your application.

test • you to create and run tests for your Apex code to ensure its functionality and
identify any potential issues.
• Test execution results and logs can be viewed within the console.

Checkpoints • Checkpoints in the Developer Console allow you to mark specific points in your
code for debugging purposes.
• When a checkpoint is reached during code execution, it provides additional
information about the variables and their values at that point.
Query Editor • The Query Editor in Salesforce Developer Console allows you to execute SOQL
(Salesforce Object Query Language) and SOSL (Salesforce Object Search Language)
queries.
• It helps you interactively query and explore data within your Salesforce organization.

view state • view state refers to the data that is associated with the visual representation of a page
and is sent to and returned from the server.
• In the Developer Console, you can monitor and analyze the view state of Visualforce
pages to optimize performance.

Progress • Progress information in the Developer Console relates to the execution progress of
your code or tests.
• It provides insights into the current state of execution, helping you identify
bottlenecks or areas that need attention.

Problem • The "Problem" tab in the Developer Console displays information about issues and
Workbench

Salesforce Workbench is a powerful, web-based suite of tools designed to interact with Salesforce.com
organizations via the Force.com APIs

• It is web-based suite of tools


• Workbench includes robust support for the Force.com Partner, Bulk, Rest, Streaming, Metadata, and
Apex API
• Allows users to describe, query, manipulate, and migrate both data and metadata in Salesforce
VS Code

Visual Studio Code is recommended IDE for Salesforce development

To work with Salesforce in Visual Studio Code, you can use the Salesforce Extension Pack, which
consolidates several useful extensions. After installing the pack, open VSCode, click on the Salesforce
icon in the activity bar, and choose "SFDX: Authorize an Org" to connect to your Salesforce org. Follow
the authentication steps, and once connected, you can create a new project using the "SFDX: Create
Project" command. This extension pack facilitates Salesforce development by providing features like
Apex language support, integrated Apex testing, and tools for managing and deploying metadata changes
to your Salesforce org directly from VSCode.
How to Setup Visual Studio Code for Salesforce

Visual Studio Code is recommended IDE for Salesforce development. In this post, we will learn about how to setup
Visual Studio Code for Salesforce development. We’ll explore the features of VS Code, configure it, and customize
it to use it as a powerful tool for Salesforce Development.

1. Download and Install VsCode


2. Install Salesforce DX CLI

To connect the VsCode with Salesforce org we need SalesforceDX CLI. Download the
Salesforce CLI from here.

Once Salesforce CLI is installed. You can


validate the same with sfdx command on
command line terminal. Check this post if you
want to learn more about Salesforce CLI
3- Install Salesforce Extension Pack for Visual Studio Code

We are almost there. Open your VsCode and Click on Extensions icon on left hand side or press
CTRL+SHIFT+X. Then Search for “Salesforce Extension Pack” and click on install button

With Salesforce Extension pack all below


extension will install automatically.

1. Apex
2. Salesforce CLI Integration
3. Apex Interactive Debugger
4. Apex Replay Debugger
5. Visualforce
6. Aura Components
7. Lightning Web Component
4. Create Salesforce DX Project

Now its time to create your first project in VsCode. To Create the project open Command Palette or
press Ctrl + Shit + P. Then type SFDX: Create Project with Manifest .

Then provide your project name and select location where you want to save your project.
5. Connect with your Salesforce Org : Authorize an Org

Our project is ready on our local machine, Its time to connect our VsCode with Salesforce. Again
open Command Palette or press Ctrl + Shit + P. This time we need to type or Select “SFDX:
Authorize an Org“.

In the last step you need to provide the org


alias name. Then it will take you to your
default browser and ask you for org
credentials. If prompted to allow access,
click Allow
7. Deploy component using Visual Studio Code

Open any file and work on your component. Now do your changes in VSCode and then
select the file which you want to deploy in your org. Then Right click on VsCode and select
the “SFDC: Deploy This Source to Org” option for deployment.
What is Debugging?
Debug log

• A debug log in Salesforce is a record of debugging information generated by the system


when executing code. It provides details about the execution flow, variable values, and
errors encountered during the execution of Apex code or system processes. Debug logs are
essential for developers to diagnose and troubleshoot issues in their code.

• To generate a debug log in Salesforce, developers can set up trace flags for specific users.
Trace flags define the scope and duration of the logging. Once a trace flag is active, the
system generates a debug log each time the specified user interacts with Salesforce, allowing
developers to inspect the log to identify and rectify issues.

• Debug logs are especially useful in understanding the sequence of events, pinpointing errors,
and optimizing code performance. Salesforce Developer Console and other tools, such as
Workbench, provide interfaces to view and analyze debug logs efficiently during the
development and debugging process.
Assignmemt 3

Install VS code on your local machine along with Salesforce Extension.

•Create Project for Assignment you had created yesterday(Introduction to Apex-Part 2).

•Fetch MathCalculator class on your local machine using VS Code

•Add subtract() method which will accept 2 integer as parameter and return subtraction.

•Save this changes to your Salesforce org using VS code.

(Hint: Implement subtract() as private static methods invoked by a public instance doMath()
method. The doMath() method will be invoked from the Execute Anonymous window)
Solution:

public class MathCalculator {


private static Integer add(Integer a, Integer b){
return a+b;
}
private static Integer multiply(Integer a, Integer b){
return a*b;
}
private static Integer subtract(Integer a, Integer b){
return a-b;
}
private static void printOutput(Integer a, Integer b){
System.debug(‘Summation of 2 values:’ + add(a,b));
System.debug(‘Multiplication of 2 values:’ + multiply(a,b));
System.debug(‘Substraction of 2 values:’ + subtract(a,b));
}

public void doMath(Integer a, Integer b){


printOutput(a, b);
}
}

In Developer Console –> Open Execute Anonymous Window


————————————————————————
MathCalculator mathCalculator = new MathCalculator();
mathCalculator.printOutput(5,3);
What is SOQL in Salesforce?

SOQL Stands for Salesforce Object Query Language. Similar to SQL,


but is designed specifically for Salesforce data. Uses the same structure and
keywords from SQL.

You can query data from Salesforce using SOQL in.

1.Apex Code
2.Developer Console
3.Salesforce REST and SOAP APIs
4.Salesforce CLI
Basics of SOQL
1. SELECT fieldlist [subquery.....]: Specify the fields you want to retrieve from the database.
You can also use subqueries to retrieve data.

2. FROM objectType: Specify the table or object type from which you want to retrieve data.

3. [WHERE conditions]: Optionally, you can add conditions to filter the rows based on
certain criteria.

4. [ORDER BY fieldOrderBy [ASC|DESC] [NULL {FIRST|LAST}]]: Optionally, you


can specify the sorting order for the result set based on a particular field. ASC is ascending,
DESC is descending. You can also specify whether NULL values should come first or last.

5. [LIMIT numberOfRowsToReturn]: Optionally, limit the number of rows returned in the


result set.

6. [OFFSET numberOfRowsToSkip]: Optionally, skip a certain number of rows before


starting to return results. This is often used in combination with LIMIT for pagination
Conditional Expressions
Conditional Operator Description

= Equals

!= Not Equals

< , <= Less Than, Less Than or Equal To

> , >= Greater Than, Greater Than or Equal To

INCLUDES, EXCLUDES Includes or Excludes Values. Applies only to Multi-Select Picklists.

Returns the records where the field values match the pattern specified after the LIKE
LIKE
operator
Selects only the records where the value of the field matches any of the values specified after
IN
IN keyword
Selects only the records where the value of the DOES NOT MATCH any of the values
NOT IN
specified after IN keyword
Conditional Expressions

•Each conditional operator mentioned in the above table returns a TRUE/FALSE value

•Build your own logic by joining multiple conditional operators using logical operators –
• AND
• OR
• NOT

•Use Apex variables for comparison in your SOQL query by adding a colon (:) before the variable
name
Aggregate Queries
•Use aggregate queries to perform the following aggregate functions on the result set –
• COUNT
• SUM
• AVERAGE
• MIN
• MAX

•Specify the field name to perform aggregation against that field in the result set

GROUP BY and HAVING Clauses


•Use the GROUP BY clause to group the result set based on the field specified

•HAVING is an optional clause used to filter the results that an aggregated function returns

•Difference between HAVING and WHERE clause is that you can use aggregated function in HAVING, but
not in WHERE.
Relationship Queries
• Write a Child-to-Parent Query
This is a child-to-parent query. It retrieves information from the Contact
object and includes fields from its related Account parent object. The
relationship between Contact and Account is typically established
through a lookup or master-detail relationship, where each Contact is
associated with a specific Account.

SELECT FirstName, LastName, Account.Name


FROM Contact

• Contact is the child object.


• Account is the parent object.
• Account.Name is used to retrieve the Name field from the
associated Account.
• Writing Parent-to-Children Queries
This is a parent-to-child query. It retrieves information from the Account
object and includes a nested query to retrieve fields from its related child
object, Contact. The relationship between Account and Contact is
typically established through a lookup or master-detail relationship,
where each Account may have multiple associated Contact records.
SELECT Name,
(Select FirstName, LastName FROM Contacts)
FROM Account

• Account is the parent object.


• Contacts is a child relationship name, and the subquery
(Select FirstName, LastName FROM Contacts) retrieves
information about related Contact child records associated
with each Account.
Writing SOQL in Apex

•SOQL query always returns a List. In Apex, create a List for the object specified in the query

•Always store the query result in a List and not a single instance

•Use for…loop for iterating over the results of a SOQL query

•Can directly write query in a for…loop for better performance


SOSL (Salesforce Object Search Language):
• SOSL is designed for searching across multiple objects at once.
• It is used when you want to perform a full-text search across multiple objects
to find records that match a search term.
• The syntax includes the FIND keyword and is optimized for searching.

FIND {John Doe} RETURNING Contact (Id, FirstName, LastName), Account LIMIT 5

• FIND {John Doe}: Specifies the search term, which in this case is "John Doe.“

• RETURNING Contact (Id, FirstName, LastName), Account: Specifies the objects and fields
to include in the search results. It will return the specified fields for matching Contact records and
the default fields for matching Account records.

• LIMIT 5: Limits the number of search results returned to 5.


Here's a table summarizing the key differences between SOQL (Salesforce Object Query
Language) and SOSL (Salesforce Object Search Language):

SOQL SOSL
Search across multiple objects for matching
Purpose Query records from one or more objects.
records based on a search term.
Resembles SQL with SELECT, FROM,
Syntax Uses the FIND keyword for full-text searches.
WHERE, etc.
Retrieving specific records based on Dynamic searching, finding records across
Use Cases
criteria. multiple objects based on a search query.
Suitable for querying related records using Not typically used for navigating relationships
Relationship Queries
dot notation. between objects.
Not designed for full-text search
Full-Text Search Designed specifically for full-text searching.
capabilities.
Query Optimization Optimized for structured querying. Optimized for search across multiple objects.
SELECT Id, Name FROM Account FIND {John Doe} RETURNING Contact (Id,
Examples
WHERE Industry = 'Technology' FirstName, LastName), Account LIMIT 5
DML Operations in Salesforce
• DML stands for Data Manipulation Language, and in the context of Salesforce and databases in
general, it refers to the set of SQL commands used for managing data within a database.
• DML operations are typically performed using Apex, the programming language for the Salesforce
platform.
• Apex allows DML operations on both List<SObject> and single SObject to update data in the database.

DML Operation Usage


insert [SObject | List<SObject>] Insert a new record or a list of records

update [SObject | List<SObject>] Update existing records with the new data specified. Existing records
are matched using the ID
delete [SObject | List<SObject>] Delete records with the matching ID from the database
Performs both insert/update on the specified records. If record ID
upsert [SObject | List<SObject>] matches, then it updates the record. Otherwise it inserts a new
record
merge SObject1 SObject2 Merges up to three records of the same SObject into a single record

undelete [SObject | List<SObject>] Retrieves a record or list of records previously deleted from recycle
bin
1- Insert: Adds new records to the database.
List<Account> accountsToInsert = new List<Account>{
new Account(Name='Test Account 1'),
new Account(Name='Test Account 2')
};
insert accountsToInsert;

2- Update: Modifies existing records in the database.

List<Account> accountsToUpdate = [SELECT Id, Name FROM


Account WHERE Name LIKE 'Test%'];
for (Account acc : accountsToUpdate) {
acc.Name = 'Updated ' + acc.Name;
}
update accountsToUpdate;
3- Delete: Removes records from the database.
List<Account> accountsToDelete = [SELECT Id FROM Account WHERE
Name LIKE 'Test%'];
delete accountsToDelete;

4- Upsert: Inserts new records or updates existing records based on an


external ID.

List<Account> accountsToUpsert = new List<Account>{


new Account(Name='Test Account 1', External_Id__c='001'),
new Account(Name='Test Account 2', External_Id__c='002')
};
upsert accountsToUpsert Account.External_Id__c;
5- Merge: Merges duplicate records.

// Assuming 'duplicateAccounts' is a list of duplicate Account records


//with the same MasterRecordId
Database.merge(duplicateAccounts, false);

6- Undelete: Restores records that have been previously deleted.

// Assuming 'deletedAccounts' is a list of previously deleted Account records


undelete deletedAccounts;
Database Methods
The Database class provides methods for performing various database operations, especially in the
context of DML (Data Manipulation Language) operations.

DML Operation Usage

insert [SObject | List<SObject>] Database.insert([SObject|List<SObject>], [Boolean


allOrNone]);
update [SObject | List<SObject>] Database.update([SObject|List<SObject>], [Boolean
allOrNone]);
delete [SObject | List<SObject>] Database.delete([SObject|List<SObject>], [Boolean
allOrNone]);
upsert [SObject | List<SObject>] Database.upsert([SObject|List<SObject>], [Boolean
allOrNone]);
merge SObject1 SObject2 Database.merge([SObject|List<SObject>], [SObject|
List<SObject>], [Boolean allOrNone]);
undelete [SObject | List<SObject>] Database.undelete([SObject|List<SObject>], [Boolean
allOrNone]);
DML : Database :

// Using Database class methods


// Basic DML List<Account> accountsToInsert = new
List<Account> accountsToInsert = new List<Account>{...};
List<Account>{...}; Database.insert(accountsToInsert);
insert accountsToInsert;
update someContacts; List<Contact> someContacts = [SELECT Id FROM
delete oldOpportunities; Contact WHERE ...];
Database.update(someContacts);

List<Opportunity> oldOpportunities = [SELECT Id


FROM Opportunity WHERE ...];
Database.delete(oldOpportunities);
Assignmemt 4

1-Write a method to insert an Account record. Also insert five related contacts to that
same account.

2.Write a SOQL query to fetch the contact records that were inserted in previous
question. (Hint: Use the CreatedDate field to add filter)

3.Write a query on Contact object and fetch the Account details. Use child to parent
relationship query.

4.Write a query on Account object and fetch the related contacts. Use the parent to
child relationship query.
Solution:
public class ApexHourAssignmentDay4 {
public void insertAccountAndContacts() {
Account acc = new Account();
acc.Name=’Apex Hour Day 4 Account’;
insert acc;
System.debug(‘Account Record has ben created:’ + acc.Name);
List listContacts = new List();
for(Integer i=1;i<=5;i++) {
Contact contact = new Contact();
contact.FirstName = 'Apex';
contact.LastName = ' Contact' + i;
contact.AccountId = acc.Id;
listContacts.add(contact);
}
insert listContacts;
System.debug('Contacts Records has been created:' + listContacts);
}
public void getRecentlyCreatedContacts(){
List listContacts = new List();
listContacts = [select Id,Name from Contact where createdDate = today];
for(Contact contact : listContacts) {
system.debug(‘Contact Name:’ + contact.name);
}
}
public void getContactswithAccount(){
List listContacts = new List();
listContacts = [select Id,Name,Account.Name from Contact];
for(Contact contact : listContacts) {
system.debug(‘Account Name:’ + contact.Account.Name);
system.debug(‘Contact Name:’ + contact.name);
}
}
public void getAccountwithContacts(){
List listAccounts = new List();
listAccounts = [select Id,Name, (select Id,Name from Contacts)
from Account];
for(Account account : listAccounts){
system.debug(‘Account Name:’ + account.Name);
for(Contact contact : account.Contacts) {
system.debug(‘Contact Name:’ + contact.Name);
}}
}}

In Developer Console –> Open Execute Anonymous Window

ApexHourAssignmentDay4 day4 = new


ApexHourAssignmentDay4();
day4.insertAccountAndContacts();
day4.getRecentlyCreatedContacts();
day4.getContactswithAccount();
day4.getAccountwithContacts();
Apex Triggers in Salesforce

Apex triggers in Salesforce are designed to help you automate specific tasks. It allows you to perform
custom actions before and after events in Salesforce. These events can include data insertions, updates
to existing data, or deletions.
What are Apex Triggers in Salesforce?

Salesforce Apex Trigger is a procedure in a database that is automatically invoked whenever a special
event in the database occurs. Triggers enable you to perform custom actions before or after events to
records in Salesforce, such as insertions, updates, or deletions.

Types of Apex Triggers in Salesforce

There are two types of triggers in Salesforce.

• Before triggers are used to perform a task before a record is inserted, updated, or
deleted in Salesforce, these are used to update or validate record values before they are
saved to the database.

• After triggers are used, if we want to use the information the Salesforce system sets
and make changes in the other records. The records that fire the after trigger are read-
only.
Trigger Events in Salesforce

An Apex trigger is a set of statements that can be executed on the following events. We can
add the events below with commas separated. Here is a list of trigger events in Salesforce.
Variable Usage
isExecuting It returns true if the trigger fires on the update operation.
isInsert It tells if the code’s current context is triggered or not.
isUpdate It returns true if the trigger fires on the delete operation.
isDelete It returns true if the code is running in the Before context.
isBefore It returns true if the code is running in the After context.
isAfter It returns true if code is running in After context.
It holds new versions of sObject in a key-value pair. This map is only available before the update,
new
after insert, after the update, and after undelete triggers.
It holds new versions of sObject in key-value pair. This map is only available before the update,
newMap
after insert, after the update, and after undelete triggers.
It holds a list of old versions of sObject records. This sObject list is only available in update and
old
deletes triggers.
It holds old versions of sObject in key-value pair. This map is only available in update and delete
oldMap
triggers.
Returns an enum of type System.TriggerOperation corresponds to the current operation.
Example of Apex Triggers in Salesforce

trigger AccountTrigger on Account (before insert, before update, after update) {


if(Trigger.isBefore && Trigger.isInsert){
System.debug('I am in AccountTrigger before insert context');
}

if(Trigger.isUpdate){
if(Trigger.isBefore){
for(Account acc :Trigger.new){
System.debug('New Name'+ acc.Name);
System.debug('Old Name'+ Trigger.oldMap.get(acc.Id).Name);
}
}
}
}
Trigger Handler pattern
The basic idea behind the Trigger Handler pattern is to separate the trigger logic into a separate
class from the trigger itself. The trigger class is responsible for registering the trigger with the
appropriate events (such as before insert or after update), and for delegating the actual logic to the
handler class.
Apex triggers are pieces of code that execute in response to certain events, such as the creation, updating,
or deletion of records in the Salesforce database.
The Trigger Handler pattern helps to keep code modular, maintainable, and scalable by separating
concerns and adhering to principles like the Single Responsibility Principle.

1- Trigger:
Create a trigger for the specific object and events you want to handle (before insert, after update, etc.).
The trigger itself should be kept minimal and only responsible for invoking the corresponding Trigger
Handler.

trigger AccountTrigger on Account (before insert, after update) {


if (Trigger.isBefore && Trigger.isInsert) {
AccountTriggerHandler.handleBeforeInsert(Trigger.new);
} else if (Trigger.isAfter && Trigger.isUpdate) {
AccountTriggerHandler.handleAfterUpdate(Trigger.new, Trigger.oldMap);
}
// Additional conditions and events can be handled as needed
}
2- Trigger Handler Class:

Create a separate class to handle the logic associated with the trigger events.
This class should contain methods for each type of trigger event (e.g., before insert, after
update, etc.).

public class AccountTriggerHandler {


public static void handleBeforeInsert(List<Account> newAccounts) {
// Logic for before insert event
}

public static void handleAfterUpdate(List<Account> newAccounts, Map<Id, Account> oldAccountMap) {


// Logic for after update event
}

// Additional methods for other events can be added


}
Assignmemt 5

• Create a Custom object Invoice with the field Total Amount.

• Create child object Invoice Line Item with Lookup relationship


to Invoice.

• Add the price field to the invoice line item.

• Write a trigger on the Invoice Line Item, which will add some of
all child records to the parent Invoice.
Writing a testclass in salesorce

Test classes in Salesforce are responsible for validating that your Apex code behaves as expected, especially when it
comes to triggers, controllers, and other logic. Salesforce has specific requirements for test classes, and they are
essential for deploying code to production.

1. Create a Test Class:

@isTest
public class AccountTriggerHandlerTest {
// Test methods will be added here
}

Begin by creating a new Apex class with the @isTest annotation. This annotation indicates that the class
contains test methods.
2. Write Test Methods:

Write test methods to cover


@isTest different scenarios of your Apex
public class AccountTriggerHandlerTest { code. Ensure that each method
@testSetup includes the @testSetup
static void setupTestData() {
// Create test data here
annotation to create test data
} that can be reused across
@isTest
multiple test methods.
static void testBeforeInsert() {
// Test logic for before insert trigger
}

@isTest
static void testAfterUpdate() {
// Test logic for after update trigger
}

// Additional test methods can be added for other scenarios


}
3. Create Test Data:

@testSetup
static void setupTestData() {
// Create test accounts
List<Account> testAccounts = new
List<Account>{
new Account(Name = 'Test Account 1'),
new Account(Name = 'Test Account 2')
};
insert testAccounts;

// Additional test data setup


}

In the @testSetup method, create test data necessary for your test methods. This can include
creating records, inserting them into the database, and setting up any required data relationships.
@testSetup ( Set Up Test Data for an Entire Test Class )

Use testsetup methods (methods that are annotated with @testSetup) to create test records
once and then access them in every test method in the test class.
Test setup methods can be time-saving when you need to create reference or prerequisite data
for all test methods, or a common set of records that all test methods operate on.

Test setup methods can reduce test execution times especially when you’re working with many
records. Test setup methods enable you to create common test data easily and efficiently. By
setting up records once for the class, you don’t need to re-create records for each test method.

Also, because the rollback of records that are created during test setup happens at the end of the
execution of the entire class, the number of records that are rolled back is reduced. As a result,
system resources are used more efficiently compared to creating those records and having them
rolled back for each test method
4. Invoke and Assert:

In each test method, invoke the


@isTest actual methods from your Apex
public class AccountTriggerHandlerTest { classes that you want to test.
Include assertions to verify that
@isTest
the expected behavior occurs.
static void testBeforeInsert() {
// Invoke the trigger handler method
AccountTriggerHandler.handleBeforeInsert(new List<Account>{new
Account(Name = 'New Test Account')});

// Query for the records and assert the expected results


List<Account> accounts = [SELECT Name FROM Account WHERE
Name = 'New Test Account'];
System.assertEquals(1, accounts.size(), 'Account should be created');
}

// Additional test methods can be added for other scenarios


}
Asynchronous Processing Basics

Asynchronous Apex is used to run processes in a separate thread, at a later time.


An asynchronous process is a process or function that executes a task "in the background"
without the user having to wait for the task to finish.
Understanding Batch Apex
Considerations for Batch Apex
•50 million records can be processed

•Use Batch Apex when there are more than 1 batches to be processed else opt for Queueable
Apex

•Fine tune your SOQL query to minimize QueryLocator records

•Invocation from Triggers may lead to uncontrolled executions

•Implement Database.AllowsCallouts to make Webservice calls


Batch Apex

Batch Apex is used to run large jobs (think thousands or millions of records!) that would exceed
normal processing limits.

Using Batch Apex, you can process records asynchronously in batches (hence the name, “Batch
Apex”) to stay within platform limits. If you have a lot of records to process, for example, data
cleansing or archiving, Batch Apex is probably your best solution.
How Batch Apex Works:

Start Method:

The start method is called at the beginning of the batch job and is responsible for collecting the records to
be processed. It returns a Database.QueryLocator object or an iterable collection of records.

Execute Method:

The execute method is called for each batch of records returned by the start method. It processes the
records in the current batch.

Finish Method:

The finish method is called after all batches have been processed. It allows you to perform any final
cleanup or logging operations.
Start
Used to collect the records or objects to be passed to the interface method execute for processing.
This method is called once at the beginning of a Batch Apex job and returns either a
Database.QueryLocator object or an Iterable that contains the records or objects passed to the
job.

Most of the time a QueryLocator does the trick with a simple SOQL query to generate the scope
of objects in the batch job. But if you need to do something crazy like loop through the results of
an API call or pre-process records before being passed to the execute method, you might want to
check out the Custom Iterators link in the Resources section.

With the QueryLocator object, the governor limit for the total number of records retrieved by
SOQL queries is bypassed and you can query up to 50 million records. However, with an
Iterable, the governor limit for the total number of records retrieved by SOQL queries is still
enforced.
Execute

Performs the actual processing for each chunk or “batch” of data passed to the method. The
default batch size is 200 records. Batches of records are not guaranteed to execute in the order
they are received from the start method.

This method takes the following:


A reference to the Database.BatchableContext object.
A list of sObjects, such as List<sObject>, or a list of parameterized types. If you are using a
Database.QueryLocator, use the returned list.

Finish

Used to execute post-processing operations (for example, sending an email) and is called once
after all batches are processed
// BatchApexExample.cls
public class BatchApexExample implements Database.Batchable<sObject> {

public Database.QueryLocator start(Database.BatchableContext context) {


// Querying for Account records where Status is 'Pending'
return Database.getQueryLocator([SELECT Id, Name, Status FROM Account WHERE Status =
'Pending']);
}

public void execute(Database.BatchableContext context, List<Account> scope) {


// Processing each Account record in the current batch
for (Account acc : scope) {
// Updating the Status field to 'Processed'
acc.Status = 'Processed';
}
// Updating the Account records
update scope;
}
public void finish(Database.BatchableContext context) {
// Perform any cleanup or logging operations after all batches have been processed
System.debug('Batch job completed successfully.');
}
}
Explanation

1. BatchApexExample Class:This is our Batch Apex class named BatchApexExample. It


implements the Database.Batchable<sObject> interface, indicating that it's a Batch Apex
class that processes SObject records.

2. Start Method:the start method is responsible for querying the records to be processed. In
this example, it returns a Database.QueryLocator containing Account records where the
Status is 'Pending’.

3. Execute Method:The execute method is called for each batch of records returned by the
start method. It processes the records in the current batch by updating the Status field to
'Processed'. The update DML statement is used to commit the changes to the database.

4. Finish Method:The finish method is called after all batches have been processed. In this
example, it simply logs a debug message indicating that the batch job has completed
successfully.
Execute - Batch Apex class

To execute this Batch Apex class, you can schedule it to run at a specific time or
manually execute it using the Developer Console or anonymous Apex.

// Anonymous Apex to execute the Batch Apex job manually


BatchApexExample batchJob = new BatchApexExample();
Database.executeBatch(batchJob);
Scheduled Apex
The Apex Scheduler lets you delay execution so that you can run Apex classes at a specified time. This
is ideal for daily or weekly maintenance tasks using Batch Apex. To take advantage of the scheduler,
write an Apex class that implements the Schedulable interface, and then schedule it for execution on
a specific schedule.
Scheduled Apex Syntax
The syntax for scheduling Apex classes in Salesforce, also known as Scheduled Apex, involves creating a class
that implements the Schedulable interface and then using the System.schedule() method to schedule the
execution of the class.

1- Create a Class Implementing Schedulable Interface:


Define a class that implements the Schedulable interface. This interface requires implementing a method
named execute().

public class MyScheduledClass implements Schedulable {


public void execute(SchedulableContext sc) {
// Code to be executed on scheduled run
}
}
2- Schedule the Class Execution:
Use the System.schedule() method to schedule the execution of your class. This method requires
specifying the name of the job, the cron expression or a Datetime value indicating when the job
should run, and the instance of the class to be executed.

String jobName = 'MyScheduledJob';


String cronExpression = '0 0 0 * * ?'; // Example cron expression: every
day at midnight
System.schedule(jobName, cronExpression, new MyScheduledClass());

• Alternatively, you can use the System.schedule(String jobName, String cronExpression,


Schedulable schedulableClass) method to schedule the job using a cron expression.
3 - Cron Expression:
The cron expression specifies the schedule for the job. It follows a specific format defining
when the job should run. For example, 0 0 0 * * ? represents midnight every day.

If you prefer to schedule the job at a specific date and time, you can use the
System.schedule(String jobName, Datetime scheduleTime, Schedulable
schedulableClass) method instead, providing a Datetime value indicating when the job should
run.
table summarizing the components of a cron expression:

Field Allowed Values Allowed Special Characters

Minute 0 - 59 ,-*/

Hour 0 - 23 ,-*/

Day of Month 1 - 31 ,-*?/LW

Month 1 - 12 ,-*/

Day of Week 0-7 ,-*?/L#

Year 1970 - 2099 ,-*/


Allowed Values: The range of values allowed for each field.

Allowed Special Characters: Special characters used to define the schedule.

,: Comma-separated values.
-: Range of values.
*: All possible values for the field.
/: Specifies increments.
?: Represents no specific value (used in either day of month or day of week).
L: Last day of the month or last occurrence of a specific day of the week.
W: Nearest weekday to a specified day.
#: Specifies the nth occurrence of a day of the week within a month.
For example:

0 0 0 * * ?: Runs the job at midnight every day.


0 0 * * * ?: Runs the job at the beginning of every hour.
0 0 12 * * ?: Runs the job at noon every day.

0 0 0 ? * 6L: Runs the job at midnight on the last Friday of every month.

Considerations for Schedulers


• Maximum 100 jobs can be scheduled concurrently
• Limit on maximum number of Scheduled Apex invocations on a per 24 hour
basis
• Synchronous Web service callouts are not supported from Scheduled Apex
Future Apex
Future Apex is used to run processes in a separate thread, at a later time when system resources
become available.

Annotations: To mark a method as a future method, developers use the @future annotation in Apex. This
annotation tells the Salesforce platform to queue the method for execution in a separate thread.

global class FutureClass


{
@future
public static void myFutureMethod()
{
// Perform some operations
}
}

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.
Methods with the future annotation can’t take sObjects or objects as arguments.
The reason why sObjects can’t be passed as arguments to future methods is because the sObject can
change between the time you call the method and the time it executes. In this case, the future method
gets the old sObject values and can overwrite them. To work with sObjects that already exist in the
database, pass the sObject ID instead (or collection of IDs) and use the ID to perform a query for the most
up-to-date record. The following example shows how to do so with a list of IDs.

global class FutureMethodRecordProcessing


{
@future
public static void processRecords(List<ID> recordIds)
{
// Get those records based on the IDs
List<Account> accts = [SELECT Name FROM
Account WHERE Id IN :recordIds];
// Process records
}
}
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). The class below has methods for making the callout both
synchronously and asynchronously where callouts are not permitted. We insert a record into a custom
log object to track the status of the callout simply because logging is always fun to do!

global class FutureMethodExample


{
@future(callout=true)
public static void getStockQuotes(String acctName)
{
// Perform a callout to an external service
}

}
Test Classes
Testing future methods is a little different than typical Apex testing. 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.

@isTest
public class MyFutureClassTest {

@isTest
static void testFutureMethod() {
// Test data setup
// Insert any necessary test records
// Start test execution
Test.startTest();
// Call the future method
MyFutureClass.myFutureMethod('Test Input');

// Stop test execution


Test.stopTest();

// Perform assertions on the results


// Query and verify the expected outcomes
}}
Test Data Setup: Prepare any test data that may be required for the test. This may involve
creating records or setting up the environment necessary for the future method to execute
properly.

Start Test Execution: Call Test.startTest() to mark the beginning of the test execution
context. This resets asynchronous limits and captures any asynchronous calls made after this
point.

Call Future Method: Invoke the future method that you want to test. In this example,
MyFutureClass.myFutureMethod() is called with a test input parameter.

Stop Test Execution: Call Test.stopTest() to mark the end of the test execution
context. This ensures that all asynchronous processes queued during the test execution are
run synchronously.

Assertions: After Test.stopTest() is called, you can perform assertions to verify that the
future method executed as expected. This may involve querying records or checking
expected outcomes.
Things to Remember
• 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. See the link in the Resources for preventing recursive future method calls.

• 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
Queueable Apex

Take control of your asynchronous Apex processes by using the Queueable interface. This interface
enables you to add jobs to the queue and monitor them. Using the interface is an enhanced way of
running your asynchronous Apex code compared to using future methods.

Queueable Apex allows you to submit jobs for asynchronous processing similar to future
methods with the following additional benefits:
Non-primitive types: Your Queueable class can contain member variables of non-primitive
data types, such as sObjects or custom Apex types. Those objects can be accessed when the
job executes.
Monitoring: When you submit your job by invoking the System.enqueueJob() method, the
method returns the ID of the AsyncApexJob record. You can use this ID to identify your job
and monitor its progress, either through the Salesforce user interface in the Apex Jobs page, or
programmatically by querying your record from AsyncApexJob.
Chaining jobs: You can chain one job to another job by starting a second job from a running
job. Chaining jobs is useful if you need to do some sequential processing.
Queueable Syntax
To use Queueable Apex, simply implement the Queueable interface.

public class SomeClass implements Queueable {


public void execute(QueueableContext context)
{
// awesome code here
}
}

Things to Remember
• You can add up to 50 jobs to the queue with System.enqueueJob in a single transaction.
• When chaining jobs, you can add only one job from an executing job with System.enqueueJob, which
means that only one child job can exist for each parent queueable job. Starting multiple child jobs from the
same queueable job is a no-no.
• No limit is enforced on the depth of chained jobs, which means that you can chain one job to another job
and repeat this process with each new child job to link it to a new child job. However, for Developer
Edition and Trial orgs, the maximum stack depth for chained jobs is 5, which means that you can chain jobs
four times and the maximum number of jobs in the chain is 5, including the initial parent queueable job.
Need Batch apex Scheduled apes Future methods Queueable apex
Process large data Yes
volumes
Execute logic at Yes
specific time
intervals
Perform web yes yes Yes
service calls
Sequential yes
processing
(chaining)
Support for nom- Yes Yes yrs
primitive (sObject,
custom Apex types)
Integrating with Salesforce
The integration refers to the process of connecting Salesforce with other systems, applications,
or data sources to exchange information and functionality. Salesforce is often integrated with
other software applications, databases, and platforms to streamline business processes, enhance
data visibility, and improve overall efficiency.
Authentication
•User Authentication
• Username / password
• Password never expires for API user
• Profiles based restrictions
• API only user
• Limits on number of failed attempts
•Authorization – Oauth
•Data Security
• How is access to data regulated?

•Network Authentication
• Login hours and IP ranges
• Org-wide trusted IP Address List
• Security Token for login via API or client outside white-listed IP
range

•Make sure the profile of the integration user meets the needs.
1.Username / Password: Users can authenticate to Salesforce using their username and password
credentials.

2.Password Never Expires for API User: In Salesforce, you can configure the password policies for
users, including whether passwords expire or not. For API users, it's common to set the password to
never expire since these users may be used by automated processes.

3.Profiles Based Restrictions: Profiles in Salesforce determine what users can do and see within the
organization. You can control access to objects, fields, and various functionalities based on a user's
profile.

4.API Only User: You can create user accounts specifically for API access. These users typically have
restricted access and permissions tailored for integration purposes.

5. Limits on Number of Failed Attempts: Salesforce imposes limits on the number of login
attempts to prevent unauthorized access. After a certain number of failed attempts, the user may be
temporarily locked out or required to complete additional authentication steps.
6. Authorization - OAuth: OAuth is a widely used authentication protocol that allows applications
to obtain limited access to user accounts on an HTTP service, such as Salesforce, without exposing
the user's credentials.

7. Data Security: Salesforce provides robust data security features, including field-level security,
object-level security, record-level security, and encryption. These features ensure that only
authorized users can access and modify data.

8.Access to Data Regulation: Access to data in Salesforce is regulated through a combination of


profiles, roles, permission sets, sharing rules, and organization-wide defaults. Administrators have
granular control over who can access what data.

9.Network Authentication: You can restrict access to Salesforce based on network authentication
settings. This includes specifying login hours, IP ranges, and requiring users to log in from trusted IP
addresses.
10. Org-Wide Trusted IP Address List: Salesforce administrators can maintain a list of trusted IP addresses
for enhanced security. Users logging in from these IP addresses may be granted additional privileges or bypass
certain security checks.

11. Security Token for Login via API or Client Outside White-listed IP Range: When accessing
Salesforce from external systems or clients outside of the trusted IP range, users must append a security token
to their password for authentication.

12. Profile of Integration User: It's crucial to ensure that the profile of the integration user is appropriately
configured to meet the specific needs of the integration, including necessary permissions, field-level security,
and access restrictions.

By implementing these authentication and security measures, organizations can effectively


control access to data and ensure the confidentiality, integrity, and availability of their Salesforce
environment.
It seems you're interested in security considerations and configurations related to Apex,
particularly focusing on session timeouts, transport security, SSL, outbound
connections, two-way SSL, port restrictions, and remote site settings. Here's a
breakdown of each:

•Apex ignores security

•Session Timeouts

•Transport Security
• SSL provides secure transport over HTTPs

•Outbound
• Two-way SSL
• Port Restrictions
• Port 80, 443, 1024-66535
• Remote Site Settings
• Sites which can be invoked from Salesforce
1.Session Timeouts: Salesforce enforces session timeouts to help protect against
unauthorized access due to inactivity. Administrators can configure session timeout settings at
the organization level to specify how long a session remains active before requiring the user to
log in again.

2.Transport Security: Salesforce employs secure communication protocols to ensure data


transmission over the internet is encrypted and secure. This includes using HTTPS (HTTP
over SSL/TLS) for web traffic to prevent eavesdropping and tampering.

3.SSL Provides Secure Transport over HTTPS: SSL (Secure Sockets Layer) and its
successor TLS (Transport Layer Security) are cryptographic protocols that provide secure
communication over a computer network. Salesforce uses SSL/TLS to encrypt data
transmitted between the user's browser and Salesforce servers.

4.Outbound Connections: Apex code running on Salesforce can make outbound


connections to external systems using various protocols such as HTTP, SOAP, REST, and
more. Administrators can control outbound connections using features like remote site settings
and named credentials to ensure secure and authorized access to external resources.
5. Two-way SSL: Two-way SSL (also known as mutual SSL authentication) requires both the client and
the server to authenticate each other using digital certificates. Salesforce supports two-way SSL for
outbound connections, allowing mutual authentication between Salesforce and external systems.

6. Port Restrictions: Salesforce restricts outbound connections to specific ports to enhance security.
Outbound connections from Apex code or Salesforce features are typically allowed only on well-known
ports such as 80 (HTTP), 443 (HTTPS), and a range of dynamically allocated ports (1024-65535).

7. Remote Site Settings: Remote Site Settings in Salesforce allow administrators to whitelist external
websites or services that Salesforce can communicate with. This ensures that Apex code can make HTTP
callouts only to approved endpoints, helping prevent unauthorized access to external resources.

By configuring and adhering to these security measures, organizations can ensure that Apex
code and integrations within Salesforce are secure, compliant, and protected against potential
security threats or vulnerabilities.
Basics of JSON

•JSON Stand for “JavaScript Object Notation”.

•Recommended for devices with low processing power or slow internet

•It is language Independent representation of objects

•Text based, human readable data exchange format

•Parsers available in many languages

•JSON can be transmitted over http / https

{
"FirstName" : “Apex",
"LastName" : “Hours“
}
JSON to Apex

JSON to Apex Deserialization

String jsonString = ‘{"FirstName" : “Apex","LastName" : “Hours"}’;


Student st = (Student) System.JSON.deserialize( jsonString , Student.class);
JSON
JSON, or JavaScript Object Notation, is a lightweight data interchange format that is easy for
humans to read and write and easy for machines to parse and generate. It is based on a subset of the
JavaScript programming language and is often used for transmitting data between a server and a
web application as an alternative to XML.

Here are some key characteristics of JSON:

1- Data Format: JSON consists of key-value pairs where data is stored as attribute-value pairs.
Each key is a string enclosed in double quotes, followed by a colon, and then its corresponding
value.

2- Data Types: JSON supports several data types, including strings, numbers, booleans, arrays,
objects, and null values. Objects are enclosed in curly braces {} and arrays are enclosed in square
brackets [].
3- Usage: JSON is widely used in web development for transmitting data between a server
and a client, especially in AJAX (Asynchronous JavaScript and XML) applications. It is also
used as a data format for configuration files, serialization, and data storage in NoSQL databases.

4- Benefits: JSON is lightweight, human-readable, and easy to parse, making it ideal for data
exchange over the internet. It is also supported by many programming languages and
frameworks.

Exemple:
{
"name": “Maral Freiji",
"age": 30,
"isEmployee": true,
"hobbies": ["reading", "traveling"],
"address": {
"city": “beirut",
"country": “Lebanon"
},
"spouse": true
}
Basics of XML
• XML stands for eXtensible Markup Language like HTML

• XML tags are not predefined. You need to define your customized tags.

• Well, the structured format is easy to read and write from programs.

<student>
<firstname>Apex</firstname>
<lastname>Hours</lastname>
</student>
JSON Vs XML
JSON XML
JavaScript Object Notation has a type like String, Extensible markup language is type less, and should be
number, Object, Boolean string
It is a markup language and uses tag structure to
It is a way of representing objects
represent data items
Retrieving value is easy Retrieving value is difficult
It does not provide any support for namespaces. It supports namespaces.
It is less secured It is more secure than JSON

Guidelines: Element – <lastname>hours</lastname>


Element Definition:
Guidelines: Key – Enclosed in double Quotes(String)
<xs:element name=”lastname” type=”xs:string”/>
Value – Can be any datatype {} – Object [] – Array , –
Attribute – <lastname lang=”EN”>Smith</lastname>
Separates data element within Object
Attribute Definition –
<xs:attribute name=”lang” type=”xs:string”/>
Which API Do I Use?

API Name Protocol Data Format Communication


REST API REST JSON, XML Synchronous

SOAP API SOAP (WSDL) XML Synchronous


Synchronous (photos
Chatter REST API REST JSON, XML are processed
asynchronously)
Analytics REST API REST JSON, XML Synchronous

Bulk API REST CSV, JSON, XML Asynchronous

Metadata API SOAP (WSDL) XML Asynchronous


Asynchronous (stream
Streaming API Bayeux JSON
of data)
Apex REST API REST JSON, XML, Custom Synchronous
REST API
1. Representational State Transfer (REST): REST is a software architectural style for designing networked
applications. It emphasizes a stateless client-server architecture, where communication between clients and
servers is achieved through standard HTTP methods (GET, POST, PUT, DELETE) and representations of
resources (usually JSON or XML).

2. Lightweight Request and Response Framework: REST APIs typically use lightweight protocols and data
formats such as JSON or XML for transmitting data between clients and servers. This lightweight approach
simplifies communication and reduces overhead.

3. Simple, Easy to Use, and Powerful Web Service: REST APIs are designed to be simple and easy to
understand. They follow a set of principles (RESTful principles) that make them intuitive to use. Despite their
simplicity, REST APIs are powerful and can handle complex operations efficiently.

4. Exposing Functionality via REST Resources and HTTP Methods: In a RESTful API, functionality is
exposed as resources, which are accessed using HTTP methods. For example, CRUD operations (Create,
Read, Update, Delete) on data are performed using HTTP methods like POST, GET, PUT, and DELETE.
5. Support for XML and JSON: REST APIs support multiple data formats for representing resources,
including XML and JSON. JSON is more commonly used due to its simplicity and lightweight nature,
especially in web and mobile applications.

6. Used in Mobile and Web Apps: REST APIs are widely used in mobile and web applications to access
backend services, retrieve data, and perform various operations. They provide a standardized way for client
applications to interact with server-side resources.

7. Resource Referencing with URIs: RESTful APIs use Uniform Resource Identifiers (URIs) to identify
resources. Each resource is represented by a unique URI, which provides a standardized way to access and
manipulate resources over the web.

Overall, REST APIs provide a flexible and scalable approach to building web services, making
them a popular choice for developing modern applications that require efficient
communication between clients and servers.
HTTP Methods

Method Action Details

HEAD Retrieve resource metadata

GET / @HttpGet Read Reads or retrieves records

POST / @HttpPost Create Creates records

PATCH / @HttpPatch Update Update fields in existing records

PUT / @HttpPut Upsert Update existing or create records

DELETE / @HttpDelete Delete Deletes records


Resources:

You might also like