You are on page 1of 29

Best Practices for Apex Code:

Lessons from the Trenches

Track: Advanced Developers

Andrew Albert, salesforce.com


Safe Harbor Statement

“Safe harbor” statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-
looking statements including but not limited to statements concerning the potential market for our existing service offerings
and future offerings. All of our forward looking statements involve risks, uncertainties and assumptions. If any such risks or
uncertainties materialize or if any of the assumptions proves incorrect, our results could differ materially from the results
expressed or implied by the forward-looking statements we make.

The risks and uncertainties referred to above include - but are not limited to - risks associated with possible fluctuations in
our operating results and cash flows, rate of growth and anticipated revenue run rate, errors, interruptions or delays in our
service or our Web hosting, our new business model, our history of operating losses, the possibility that we will not remain
profitable, breach of our security measures, the emerging market in which we operate, our relatively limited operating
history, our ability to hire, retain and motivate our employees and manage our growth, competition, our ability to continue to
release and gain customer acceptance of new and improved versions of our service, customer and partner acceptance of
the AppExchange, successful customer deployment and utilization of our services, unanticipated changes in our effective
tax rate, fluctuations in the number of shares outstanding, the price of such shares, foreign currency exchange rates and
interest rates.

Further information on these and other factors that could affect our financial results is included in the reports on Forms 10-
K, 10-Q and 8-K and in other filings we make with the Securities and Exchange Commission from time to time. These
documents are available on the SEC Filings section of the Investor Information section of our website at
www.salesforce.com/investor. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-
looking statements, except as required by law.
Andrew Albert
Technical Evangelist
Raise your hand if….
What I hope you take away

ƒ Understand the value of governor


limits

ƒ Learn key coding principles and best


practices

ƒ Understand the differences of


executing Apex synchronously vs.
asynchronously
Agenda

ƒ Why is Apex different?


ƒ Importance of Governor Limits
ƒ Tips for writing efficient, scalable Apex
ƒ Asynchronous Apex
ƒ Additional Resources
ƒ Q&A
Why is Apex different?
ƒ Compiled and executed on the
Force.com multi-tenant architecture

ƒ Shared resources across all customers,


partners, and developers

ƒ Critical that Apex code uses


infrastructure resources efficiently

ƒ This where governor limits come in….


Governor Limits
ƒ Runtime limits to ensure that an Apex
request does not monopolize shared
resources.

ƒ Memory; Database; # of script


statements; # of records processed,
ect..

ƒ Not a new concept. Just a new term.

ƒ Guarantee no implementation of Apex


will negatively impact other
salesforce.com instances.
How are they calculated?
ƒ Calculated at runtime

ƒ Key factors:
– How was the Apex request
invoked?
– How many records initiated
request?
– What resource is in question?

ƒ Scope is the entire Apex request


Trigger Scenario & Governor Limits
Calculation
• Update Contacts through API
• Trigger logic on Contact

Entry
Point

Integration
Logic updates
updates 100 Trigger on Trigger fires
related
Contacts Contacts on Accounts
Accounts
through API

Apex Request Scope


Visualforce & Controller Scenario
• Visualforce page with Buttons
• User clicks two buttons

Entry Entry
Point #1 Point #2

Controller User clicks Controller


VF Page User clicks Apex logic Returns to
method another method
loads a button executes Page
executes button executes…

Apex Request Scope #1 Apex Request #2


Let’s look at how we can write governor-friendly
code that is efficient and scalable.

Let’s turn that frown upside down!


Sample Code #1: Bulkify Triggers

Common Issue:
– Coding a Trigger to only process a single
record
Sample Code #1: Bulkify Triggers

Best Practices:
– Always design the trigger to process the
array of records
– Iterate across the entire Trigger.new
collection; not just the first record.

Benefits:
– Trigger handles both UI operations and
API operations (single and batch
operations)
Sample Code #2: Efficient SOQL, DML & Loops

Common Issue:
– Too many Queries
– Too many DML statements
– Too many script statements
Sample Code #2: Efficient SOQL, DML & Loops
Best Practices:
– No SOQL queries inside Loops
– No DML statements inside Loops
– Use Collections in SOQL Where Clause to get
all records back in single query
– Execute DML statements with a Collection; not
individual records per DML statement

Benefits:
– Improved performance of operation
– Avoid governor limit exceptions by executing
SOQL and DML with Collections.
– Minimize impact on governor limits
Sample Code #3: Efficient Loops, Query
Relationships & Helper Methods

Common Issue:
– Inefficient FOR Loops
– Inefficient Statement control (ie more logic
than needed)
– Poorly designed helper method (not
bulkified)
Sample Code #3: Efficient Loops, Query
Relationships & Helper Methods

Best Practices:
– Streamline FOR Loops
– Avoid redundant iterations
– Use SOQL Relationships to reduce # of
queries
– Bulkify your helper methods

Benefits:
– Execute less lines of code
– Avoid governor limit exceptions with
poorly designed shared Apex methods
– Minimize impact on governor limits
Asynchronous Apex
ƒ Offload some of the processing by creating a
separate, independent Apex request that runs
asynchronously

ƒ Enhances user experience

ƒ Higher governor limits (as compared to with Trigger


limits)
– Same as Visualforce Controller or WSDL Method

ƒ Define async apex methods with @future annotation


Trigger Scenario & Async Apex
• Update Contacts through API
• Trigger logic on Contact

Integration
Calls @future
updates 100 Trigger on Apex
method with
Contacts Contacts completes
Contacts
through API

Enqueue Async Apex

@future SOQL, DML


Acount
Method updates Apex
Trigger
invoked Contacts, Completes
invoked
Accounts
Sample Code #4: Asynchronous Apex

Common Issue:
– Not all Apex logic needs to be
synchronous
– Asynchronous apex classes and methods
are not ‘bulkified’
Sample Code #4: Asynchronous Apex

Best Practices:
– Use @future annotation for Apex logic that does not
need to be synchronous.
– @future methods should be bulkified

Benefits:
– @future Apex gets higher governor limits than Trigger
invocations.
– Better user experience since logic is offloaded to run
asynchronously.
– Avoid governor limit exceptions when executing a
batch of records
– Minimize impact on governor limits
Summary of Key Concepts

Always Bulkify Use


Use Collections
asynchronous
• Triggers (Sets, Lists,
• Methods apex (@future)
Maps)
• Async Apex Methods where possible

Keep SOQL Streamline Loops Use Apex Limits()


queries outside of (avoid methods in your
Loops redundancies) Apex code

Keep DML Streamline


statements queries – avoid
outside of Loops redundant
queries
Agenda
ƒ Why is Apex different?
ƒ Importance of Governor Limits
ƒ Tips for writing efficient, scalable Apex
ƒ Asynchronous Apex
ƒ Additional Resources
ƒ Q&A
Additional Apex Resources
ƒ Apex Governor Limits article
– http://wiki.developerforce.com/index.php/Governors_in_Apex_Code

ƒ Apex Best Practices article


– http://wiki.developerforce.com/index.php/Apex_Code_Best_Practices

ƒ Apex Technical Library


– http://wiki.developerforce.com/index.php/App_Logic

ƒ Discussion Boards
Recommended Sessions

ƒ Upcoming Dreamforce Sessions


– Designing Your Apps for Commercial Success
(Thursday, 2:45pm, Esplanade 305)
– Architecting in the Cloud: Choosing the Right Technologies for
Your Solution (Friday, 11:30am, Esplanade 305)
– Meet the Force.com Platform Development Team
(Friday, 11:30am, Esplanade 309)

ƒ Please visit us at the Force.com Zone!


Summary of Key Concepts

Always Bulkify Use


Use Collections
asynchronous
• Triggers (Sets, Lists,
• Methods apex (@future)
Maps)
• Async Apex Methods where possible

Keep SOQL Streamline Loops Use Apex Limits()


queries outside of (avoid methods in your
Loops redundancies) Apex code

Keep DML Streamline


statements queries – avoid
outside of Loops redundant
queries
Next Steps

‰ Slides, video, & other resources related to this session are on the web
http://developer.force.com/dreamforce
‰ Don’t go home without a Workbook and set of Developer Cheat Sheets
– available for free in the Force.com Zone
‰ Explore deploying your app to up to 100 users for free, thanks to
the new Force.com Free Edition
‰ Help us help you, and maybe win an iPod! Please provide session
feedback online this year:
ƒ Log in to the Dreamforce attendee portal or find the Survey Counters in Moscone
North or South lobbies
ƒ 14 iPod Nanos given away each day; fill out all the surveys to increase your chances!
QUESTION & ANSWER
SESSION

Andrew Albert
Technical Evangelist

You might also like