This document provides an overview and introduction to Apex for developers. It begins with an introduction to Apex and the Salesforce platform. It then outlines the agenda which includes an overview of the platform, writing Apex classes, accessing data using SOQL and DML, writing triggers, and additional topics like Visualforce, REST APIs, and unit testing. It encourages participants to use their developer environment and provides a link to sign up. It describes what will be built in the session which is an app to manage sessions and speakers at a conference. It includes two forward-looking statements disclaimers.
4. Forward-Looking Statements
Statement under the Private Securities Litigation Reform Act of 1995:
This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties
materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or
implied by the forward-looking statements we make. All statements other than statements of historical fact could be deemed forward-looking,
including any projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements
regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded
services or technology developments and customer contracts or use of our services.
The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality
for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and
rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of any litigation, risks associated with
completed and any possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our
ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer
deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further
information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-K for the
most recent fiscal year and in our quarterly report on Form 10-Q for the most recent fiscal quarter. These documents and others containing
important disclosures are available on the SEC Filings section of the Investor Information section of our Web site.
Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available
and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that
are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
6. Expectations
You are an experienced developer
You are curious about Apex but no experience
You are ready to learn something
You are ready to build something, too.
It is a 90 minute workshop: you will not leave here an expert.
7. Agenda
Platform Overview
Writing Apex Classes
Accessing Data using SOQL
Writing Triggers
Extra Credit:
Writing Visualforce Pages
Writing Controller Extensions
Using the REST APIs
Unit Testing
Batching and Scheduling
10. App Cloud Makes Building Apps 70% Faster
The fastest path from idea to App
Idea
Legacy App Dev: 6-12 Months
Build on modern platform
services with advanced
tools Connected Desktop and
Mobile Apps
Idea App
install
complex
software
build
app
make it
mobile &
social
build & test
security
buy & setup
hardware
define user
access
setup
reporting &
analytics
Source: IDC White Paper, sponsored by Salesforce.com, Salesforce Platform: Accelerate App Dev with Huge ROI, Doc #246505, Feb 2014.
11. Bulk
REST
Metadata
SOAP
Tooling
Streaming
INTEGRATIONLAYER
Point & Click
Integration Tools
Page
Builder
DECLARATIVE DEVELOPMENT
GLOBAL ENTERPRISE CLOUD INFRASTRUCTURE
PLATFORM SERVICES
APP MANAGEMENT & DEPLOYMENT
Workflow
Engine
UI FrameworkSharing &
Permissions
Global
Search
Reports &
Dashboards
Files
& Content
Authentication CollaborationEvent Log
Framework
Translation
Workbench
App
Builder
Process
Builder
Schema
Builder
Multi-Tenant Network
& Firewall
Auto
Updates
Backup &
Geodiversity
Security Trust
IDECLI Agile
Accelerator
Store
Builder
Dev
Console
Sandbox
Metadata
Heroku DX node.js
PROGRAMMATIC DEVELOPMENT
Database Smart
Containers
Heroku
Add-ons
Heroku
Button
Ruby
Identity
Global
Data Centers
Data
Storage
Single code
base
Python Java APEXPHP
Offline
Salesforce1 Mobile
Container Geolocation
Push
NotificationsSDK Mobile Identity
MOBILE SERVICES
Community
Builder
Page
Builder
App Cloud Gives You Tools for Building Any App
Full spectrum of capabilities from enterprise control to elastic flexibility
12. Two Approaches to Development
Visualforce Pages
Visualforce Components
Lightning Components
Apex Controllers
Apex Triggers
Metadata API
REST API
Bulk API
Formula Fields
Validation Rules
Workflows and Approvals
Process Builder
Custom Objects
Custom Fields
Relationships
Page Layouts
Record Types
Lightning App Builder
User
Interface
Business
Logic
Data
Model
Declarative Approach Programmatic Approach
Point and Click Code
13. The Conference App
What we’ll build…
Schema for sessions and speakers (to be installed via package)
Automatically send confirmation emails
Perform validation against other data
Customized user interface with Visualforce Pages
Upload speaker pictures
Flickr integration (Apex) to show conference pictures
14. Lab 1: Setup Your Developer Org
• Create org (if not already done)
developer.salesforce.com/signup
• Install Package
bit.ly/tdx-16-apex-test-1
• Verify Steps 1 and 2 of Project
bit.ly/tdx-conf-app
16. What is Apex?
Force.com-native programming language
Object-oriented (Classes, Interfaces, Inheritance)
Tenant Secure
Syntactically similar to Java and C#
Compiles to Java bytecode
Strongly typed
17. I've Heard Apex is a Bit Funny
Not a stand-alone language
Compiled only on the server…no local compiler
Governor limits
18. Apex Syntax Constructs
Primitive data types
Flow control (if, for, while, …)
Exception handling
Collections: List, Set, Map
Case insensitive
Single-quotes for strings: 'Joe'
Lines terminated with semicolons
19. Apex Language Features
Id data type
SObject class
Built-in support for data access
Built-in test framework
20. Apex Class
public class MortgageCalculator {
}
public Double amount { get; set; }
public Double rate { get; set; }
public Integer years { get; set; }
public Double calculateMonthlyPayment() {
Integer months = years * 12;
Double monthlyRate = rate / (12 * 100);
return amount * (monthlyRate/
(1 - Math.pow(1 + monthlyRate, -months)));
}
25. What's SOQL?
Salesforce Object Query language
Similar to SQL
Streamlined syntax to traverse object relationships
Built into Apex
Read Only (We have different syntax to change data)
29. Sort Order
SELECT Id, Name, Phone
FROM Contact
WHERE MailingCountry = 'Spain'
AND Name LIKE '%rosa%'
ORDER BY Name
30. Limit Rows Returned
SELECT Id, Name, Phone
FROM Contact
WHERE MailingCountry = 'Spain'
AND Name LIKE '%rosa%'
ORDER BY Name
LIMIT 50
31. Query Including Parent Data
SELECT Id, Name, Phone, Account.Name
FROM Contact
WHERE MailingCountry = 'Spain'
AND Name LIKE '%rosa%'
ORDER BY Name
LIMIT 50
32. Query Including Child Data
SELECT Id, Name, Phone, Account.Name
(SELECT FirstName, LastName, Phone
FROM Contacts)
FROM Account
...
34. Inline SOQL in Apex: Handling Result
List<Session__c> sessions = [SELECT Name, Type__c
FROM Session__c];
Integer i = [SELECT Count() FROM Session__c];
Returns List, sObject, or Integer
Type check on compile
35. Inline SOQL in Apex: Filter Variable
String level = 'Advanced';
List<Session__c> sessions = [SELECT Name, Level__c
FROM Session__c
WHERE Level__c = :level];
36. Inline SOQL in Apex: List Filter Variable
List<String> levels = new List<String>();
levels.add('Intermediate');
levels.add('Advanced');
List<Session__c> sessions = [SELECT Name, Level__c
FROM Session__c
WHERE Level__c IN :levels];
37. Inline SOQL in Apex: As Iterator
for (Speaker__c s : [select email__c from Speaker__c])
{
System.debug(s.email__c);
//...or maybe do something meaningful...
}
38. Changing Data: DML
Data Manipulation Language
Syntax to create, update, delete records
Keyword syntax:
insert myRecord;
Static method of Database class:
Database.insert(myRecord);
41. update
String oldName = 'Apex 101';
String newName = 'Apex for Beginners';
Session__c session = [SELECT Id, Name FROM Session__c
WHERE Name=:oldName];
session.name = newName;
update session;
42. delete
String name = 'Testing 501';
Session__c session = [SELECT Name FROM Session__c
WHERE Name=:name];
delete session;
43. Lab 3: Accessing Data using SOQL and DML
Execute SOQL statements in the Query Editor
Execute DML statements in the Anonymous Window
44. What Else Should I Know?
• SOQL and DML Governor Limits
• Aggregate SOQL queries
• Dynamic SOQL using Database.query
• QueryLocator for large query results
• Full text search with SOSL
• Other DML: Upsert, Undelete, SavePoint/Rollback, etc.
46. What's a Trigger?
Apex code executed on database events
Before or after:
Insert
Update
Delete
Undelete
47. Before or After?
Before
Update fields on this record en route to database
Example: set default/calculated values
After
Create related records, access DB-generated values, async callouts
Example: Send speaker confirmation email
48. Think Bulkification
Trigger API is designed for batch operations
Data Import, Bulk API, REST composite/tree endpoint, etc.
Triggers work on collections of records, not single records
Context variables provide access to data:
Trigger.old and Trigger.new (List<SObject>)
Trigger.oldMap and Trigger.newMap (Map<Id,SObject>)
49. Example 1: DML and Loops
trigger WelcomeKit on Account (after insert) {
List<Case> myCases = new List<Case>();
for (Account account : Trigger.new) {
Case welcomeCase = new Case();
welcomeCase.Subject = 'Mail Welcome Kit';
welcomeCase.AccountId = account.Id;
myCases.add(welcomeCase);
}
insert myCases;
}
List Iterator
DML Outside Loop
50. Example 2: Check for Update
Trigger on Account (before update) {
for (Account acc: Trigger.New) {
// Compare new value with old value
if (acc.Rating != Trigger.oldMap.get(acc.Id).Rating) {
// Your Logic
}
}
}
52. Declarative vs Trigger
Process Builder/Workflow Trigger
Created with Clicks Code
What can it do • Update field
• Send email
• Create records
• Post to Chatter
• Launch flow (flow trigger)
~ Anything (e.g.
create/delete records, REST
callout, etc.)
Cross-object field updates Limited (detail -> master) Any
53. Lab 4: Writing Triggers
Write the SendConfirmationEmail trigger
Write the RejectDoubleBooking trigger
54. What Else Should I Know?
• Order of Execution
• Batch Size Limits for Trigger Execution
• Transaction Persistent Static Variables
• Recursive Trigger Control
• Asynchronous Apex
• Trigger Patterns
• Apex Tests
Originally these sessions were timed for 2.5 hours. We have an hour less, bringing us to only be able to do up to the point where we do a trigger.
Cover the agenda only as the use case will be described in a later slide.
Cover the agenda only as the use case will be described in a later slide.
This project is a 3-4 hour project. We will make a start and cover some basic Apex functionality. Most of this will be copy/paste, but we will review the code and discuss and cover questions.
If you've not done so already please sign up for a free developer edition org.
They should create a brand new DE org if they have not done so recently. They should not use a Trial, Sandbox or Production org.
Emphasize our DE orgs are free and do not expire (they are not product trials)
Key Takeaway:
Traditional app development is time consuming, with many steps that have to be managed. App cloud offers managed services that remove these steps, making it possible to build more apps, faster.
Talk Track:
App Cloud gives you everything you need to build apps fast and get started right away, right out of the box. Instead of buying and setting up hardware, software, networking, and piecing together a dev stack, you can focus on solving the business problem. App Cloud your fastest path from idea to app, meaning that you can now build all of the apps your business needs.
Animate top to bottom
The features we will build will automatically be available to the Salesforce1 mobile app.
Explain high points of Salesforce1
Completely configurable
Mobile solution for internal/employee facing apps
This workshop covers the programmatic side, but before you start coding, it's always a good idea to ask yourself if what you are about to code can't be done declaratively. i.e Do I need to write that trigger, or can the same thing be done using a workflow?
This workshop covers the programmatic side, but before you start coding, it's always a good idea to ask yourself if what you are about to code can't be done declaratively. i.e Do I need to write that trigger, or can the same thing be done using a workflow?
Much of what you need to do for a Salesforce project will be done with the point-and-click configuration of the org. Coding is done when you need more flexibility than the point-and-click features allow.
We’re going to go through adding in programmatic functionality to an installed schema for a conference management app. This demo app manages a conference in a similar way to how we run Dreamforce—objects for sessions, speakers, and automation for session management.
If you didn't finish, please sign up.
And install the package for the app data model.
I've now tested that this package will pass both of the first two challenges in the conference management app
Stuff that will feel familiar to people. Trying to speak of broadly important architectural attributes of the language.
Most of this will be straightforward.
Tenant-secure
In a multi tenant system, code must execute in a way that distinguishes the tenant (org/customer) that the code is executing for. This is completely built-in to the Apex runtime context. It is impossible to execute Apex code that accidentally accesses data from another tenant. If you need to access data from another Salesforce environment via Apex, you can, but you must use the standard public API for that environment using a user and session for that environment, after authorizing against that other environment. There are other integration mechanism like Salesforce Connect or S2S, too, but these also require some kind of authorization. Apex can't cross the boundary between orgs without being authorized first.
Points for each of these:
Not Stand-alone
You can't just write a new app with Apex. Apex fires when certain system events invoke it. As such, the language is tightly coupled with the environment, working with objects, fields, and other artifacts represented in metadata. As such, without a full representation of the environment you cannot execute meaningful code without the full picture of the environment.
Server-only compiled
Because of the first point, there is no compiling Apex outside of the environment either.
Governor Limits
Every computer system has limits on resources (memory, cpu, db connections, etc.). In a multi tenant system, these must be metered so that no one tenant causes pain to another tenant because of bad customizations. In the Apex runtime context we do this with governor limits: execution limits metered on each transaction.
I like to talk to developers about Apex being a "JVM-Based Salesforce DSL".
Apex is very Java like. It also has some features that resemble C#.
Apex is very Java like. It also has some features that resemble C#.
Poll the audience about their experience level with Apex before walking through this slide so you know how deep you need to talk about it
Points that could be called out:
Public class – what it means, could be public with sharing (and what that means)
Variable declaration (public, data type, instance variable name) and a getter (allows your VF page to get this value to display it) and a setter (allows your VF page to set the value from a form)
Method
Similar syntax to Java, right? The only thing missing from this sample is a constructor which is optional for being able to initialize values
Note: you don't need to know all of these or even read them. The point here is that there is an ecosystem of developers building tools for developers.
You have a lot of options for development environments…
The Developer Console is a comprehensive suite of developer tools that is included with your DE and doesn’t require any software downloads.
There are also a lot of open source projects that exist with a great set of tools like the Force.com IDE on eclipse or the MavensMate plugin for Sublime…
If you prefer to use the command line, the Force CLI has a lot of helpful tools for being able the import/export data and do migrations from a command line
For the exercises today we’re going to use the Developer Console…that way you don't have to have anything installed.
For our first hands on exercise we’re going to need to install the custom schema package which will include all of the custom objects for our conference management app. We’re going to create an email manager class and execute that Apex anonymously to see how it works.
Why do we have SOQL and this different syntax to change data?
(I think) because SOQL predates Apex and existed to support API calls long before Apex existed.
Lets walk through the anatomy of a SOQL statement… This is the most basic form of a SOQL statement and you can see it looks a lot like SQL. You query for a set of records, specify which fields you want to grab values for, and then specify the Salesforce object that you’re trying to query
But SOQL has limits, and will throw an error if you are trying to query too big of a data set. You can start narrowing down the result set by adding a WHERE clause
The WHERE clause can be a concatenation of multiple logical expressions, like in this case where we are looing for a contact who has a defined phone number and the name is like the string ‘rose’. The percent symbols before and after is like placing a wildcard where text could come before or after rose. Melrose and Roselyn would both fit into this category.
Lists in Salesforce can be ordered and indexed, so you can specify how you would like to order it right from within the query
And again, coming back to limits. You can specify a limit on your records returned.
You can also query for fields on the parent object through a relationship field. If this were a custom object you were traversing, like Session__c for example, you would need to use Session__r.FieldName to traverse through the relationship field to grab the parent’s field values.
You can also go the opposite way and grab all related child records and their associated field values.
You can copy and paste one of the SOQL statements above into the Query Editor, or come up with one on the fly. Other samples here: https://developer.salesforce.com/blogs/developer-relations/2013/05/basic-soql-relationship-queries.html
If you have a sample aggregate query, join, or common practice feel free to use your own sample!
Aggregate Sample:
AggregateResult ClosedWonOpptys = [select SUM(Amount) totalRevenue, CALENDAR_MONTH(CloseDate) theMonth, COUNT(Name) numOpps
from Opportunity
where AccountId =: acctId
and StageName = 'Closed Won'
and CALENDAR_MONTH(CloseDate) =: thisMonth
GROUP BY CALENDAR_MONTH(CloseDate) LIMIT 1];
You can directly assign SOQL query returned single values and collections to variables in Apex.
Return types for SOQL are List of sObject, sObject, or Integer.
When you use inline SOQL, your query will be type checked at compile time.
You can assign returned SOQL query set to a collection variable
You can use variables as control variables for your WHERE clause
Variables can be single values or collections of sets or lists
You can also directly use a SOQL statement in a for loop or a return statement on a method
If questions arise about which to use mention flexibility of the method for transaction control (all_or_none true/false).
There is a lot of dml we are not covering: upsert, undelete, setSavePoint, rollback, convert (for lead),
There are multiple syntactical ways you can create records.
Every sobject has a constructor that will accept a variant number of input parameters that map to the fields of that object.
You must have an Id field value for update.
If it comes up, you can mention upsert, but in that instance Id is not required if you have an external id field value.
If you want to mention where is the ID?
That it is implicit in SOQL when using in Apex. (Not the same as in the API…API will only query exactly the fields you specify.
You can demo this in the query tool in Developer Console (which uses the API).
Leah, add to this as you see fit, or remove what you don't want to talk about
We are IT professionals and never shy away from making up words when we need to.
Best practice for triggers is to BULKIFY!
Best practice: don’t do SOQL statements or DML operations inside of a for loop
Work with collections of data in lists, sets, or maps and limit API calls
Old: data values before this current transaction
New: new values being updated for this transaction
Walk through building this trigger
Why is it afgter insert?
Loops through a potential single to large set of records depending on whether or not it was a data load of multiple records
Trigger.new
Bulkified! Insert outside of the for loop
Why is it before? (you don’t want to go into an infinite loop modifying an account and if you want to compare against an old value, you need to use a before trigger for access to the oldMap
But what about the principle of click first, then code?
Leah, add to this as you see fit, or remove what you don't want to talk about
When building custom pages, Visualforce uses the MVC design pattern which is the most commonly used design paradigm in all of enterprise computing.
It allows you to tackle each facet of the application development separately, while allowing each member to interoperate
you’ll notice metadata is in the model, view, and controller. This is because the platform creates, abides by, and uses the rich metadata attached to every object and programmatic component.
To start at the base, or your model, this is your data and configurations around those objects. When coding on Force.com, in order to pull that data onto a web page for an end user to view, you need a controller to control your view-model interaction. These will also control how the page works, and how it interacts again with the database and could be a standard controller (no apex) or a custom controller or controller extension (apex). Finally, to build a view, you can create a Visualforce page when the standard page layout doesn’t meet your needs.
Simplest VF page
Always has a page tag as the first/last line
This uses a global user instance variable to grab the logged in users info
Standard controller can be both a standard object and a custom object
All inputs an actions must happen within a form tag
The save method uses the standard controller to create/save a contact
If there were a contact Id in the url, the page would know to pre-populate the inputs with the appropriate field values to be saved/updated
Yelp page
Twitter bootstrap and visualforce: https://developer.salesforce.com/blogs/developer-relations/2014/03/twitter-bootstrap-and-visualforce-in-minutes.html
The main thing to call out here is the parameter for the standard controller in the constructor
Also call out how it assigns the standard controller to an ApexPages.StandardController variable that can be used throughout the entire class
Also, to use the individual record grabbed by the standard controller through the Id field in the URL that accessed the page, you need to caste the Sobject type to the standardController object type
The main purpose of this class is just to show that the controller has totally custom functionality, and when you don’t have another standard or custom controller and this is the primary (and solo) controller, you no longer are required to have a constructor
Intro: Our leading application, Sales Cloud, is now reinvented as Sales Cloud Lightning.
Notes: Sales Cloud Lightning is the first step in connecting to your customer in a whole new way. You can sell the way you want- With over 20 new components, you can use on you can use on top of your metadata & existing sales cloud data, along with a robust ecosystem and app exchange that will transform the way you sell.
We are very excited to welcome SteelBrick to the Salesforce family, now you can Sell faster with a complete quote to cash solution all within the Lightning experience.
You can sell smarter with SalesforceIQ, our intelligent email app and our Sales wave app. Sales Wave is the best analytics for sales cloud users. It’s an easy to use application designed for sales professionals. All of your sales cloud data turned in to KPIs so you can make smarter decisions.
And of course you can sell from anywhere with our Salesforce1 Mobile app, with all of your sales cloud data at your fingertips.
Intro: Our leading application, Sales Cloud, is now reinvented as Sales Cloud Lightning.
Notes: Sales Cloud Lightning is the first step in connecting to your customer in a whole new way. You can sell the way you want- With over 20 new components, you can use on you can use on top of your metadata & existing sales cloud data, along with a robust ecosystem and app exchange that will transform the way you sell.
We are very excited to welcome SteelBrick to the Salesforce family, now you can Sell faster with a complete quote to cash solution all within the Lightning experience.
You can sell smarter with SalesforceIQ, our intelligent email app and our Sales wave app. Sales Wave is the best analytics for sales cloud users. It’s an easy to use application designed for sales professionals. All of your sales cloud data turned in to KPIs so you can make smarter decisions.
And of course you can sell from anywhere with our Salesforce1 Mobile app, with all of your sales cloud data at your fingertips.