001 Developer Fundamentals 23% Notes
001 Developer Fundamentals 23% Notes
Platform Basics
One of the things that separates the platform from other software-as-a-service
(SaaS) offerings is that it relies on a metadata-driven architecture. Everything,
including the code, configuration, and apps, is specified as metadata.
As .NET developers, you’re probably already familiar with the cloud applications that
run on Microsoft Azure. Well, the Lightning Platform works differently. The Lightning
Platform is tightly integrated with the database. You also get all sorts of things, like
user interface, security, and reporting, built right in with the platform. This integration
is what lets you build apps super fast.
BUT - On the Lightning Platform, we don’t have to worry about setting up nodes or
management tasks. You don’t have to worry about upgrading, tuning, or scaling anything. To
be honest, you probably won’t miss all that added complexity and responsibility, because
instead you can just focus on quickly building great apps.
Apex Basics
Because the Lightning Platform is so tightly integrated and relies on a metadata architecture,
you can accomplish an awful lot using declarative development, or what is known as “point-
and-click” app building.
As a .NET developer, on the Lightning Platform, code is not always needed. But it’s important
to understand when code is needed and when it isn’t. You can learn more about this
distinction by browsing this article on when to click and when to write code.
What Is Similar?
The Apex programming language is similar to C#. Apex is saved, compiled, and executed
directly on the Lightning Platform. Like C#, it’s object oriented. In this section, we’ll go
over this and what else makes it similar to .NET languages.
Object-oriented Design
Apex supports many of the object-oriented principles that you’re probably used to, such as
encapsulation, abstraction, inheritance, and even polymorphism. In fact, the Apex language
includes many language constructs you’re already familiar with, including classes, interfaces,
properties, and collections.
For example, here is what an Apex class named HelloWorld would look like.
This simple HelloWorld class includes one method named printMessage that is used to
simply output the message “Hello World” to the system debug log.
The basic syntax for defining classes is: - + A link to Understand Classes
Check out Understanding Classes to learn more about how classes, objects, and interfaces
work.
https://developer.salesforce.com/docs/atlas.en-
us.apexcode.meta/apexcode/apex_classes_understanding.htm?_ga=2.2105456.1326458405.1
712477921-919194799.1675078093
You can also add values to the list after it has been created, Like so:
You’ll probably create a lot of list variables in your Apex development, because the output of
every SOQL query is a list. For example, you could create a list of Accounts using code such
as the following:
Like arrays, lists have indexes that start at zero. So you could access the name of the first
account in the list with code like this:
Set
A set is an unordered collection of elements that does not contain duplicates. A set is
commonly used to store ID values because the value are always unique.
You could then use the set as part of a WHERE clause in a SOQL query.
For example, here we’re creating a set that contains two unique IDs for Accounts. We then
use the set in the SOQL query to return Accounts only for those IDs.
Map
A map is a collection of key-value pairs. Each key maps to a single value.
A map is useful when you need to quickly find something by a key. The key values must be
unique, so you could have a map that contained ID values for the key and then mapped to
an sObject.
For example, you could use the following code to declare a map variable named accountMap
that contains all Accounts mapped to their IDs.
You could then access a specific Account record using the get method and code
similar to the following.
Check out the official docs to learn more about the data types that Apex supports.
ASP.NET to Visualforce
There are many similarities between the two., most notably, a clear separation of the
markup from the code. You also use form fields to map code to properties defined in
the controller.
The bad news is that viewstate is just as much a pain with Visualforce as it is with
ASP.NET due to the fact that HTTP is stateless ☹.
The good news is that there are ways around the viewstate limitations. 😊 (Learn
more by checking out the link in Resources.)
Visualforce is a framework for rendering HTML pages using an MVC paradigm. You
can use either one to render web pages, and both separate the application logic
from the markup and the database model, but they do so in different ways.
To learn all about Visualforce, check out the Visualforce Basics module (Later on in
this trailmix). For now, we just want to give you a basic idea of how it works by
showing you an example. You can use the following markup code to render a
simple page used to enter Contact data.
This example uses what is known as a standard controller, which is part of the Lightning
Platform. It’s basically system-generated code that allows you to quickly incorporate
basic CRUD functionality in your Visualforce pages. Before you start getting worried, just
know that you can create your own custom controllers to add in more complex functioning.
Learn all about how standard and custom controllers work in the Visualforce Basics module.
The rendered version of this page looks like the following:
*Lightning is a lighter weight way of delivering super fast and responsive web apps, but
Lightning is a component-based framework. (More in future module here in the Trailmix)
What Is Different?
• For starters, unlike C#, Apex is not case sensitive.
• Apex and Database are Tightly Coupled
Apex code and the Lightning Platform database are tightly coupled to the point where they
are sometimes indistinguishable. Each standard or custom object in the database has a
"mystical" representation via an Apex class that provides all sorts of functionality to make
interacting with the database a snap.
The class and its underlying object are essentially a mirror image of one another that is
constantly in sync. For instance, whenever you create a new field in an object, a class
member is automatically surfaced to reference the values in the database. It's also impossible
to add a reference in your Apex code to a field that doesn't exist; the compiler will return an
error and simply not save your code. The platform works hard to ensure these dependencies
and won't let the database schema and your code become out of sync. Therefore, if you
attempt to delete a custom object or a field that is referenced by Apex code, the platform
will raise an error and disallow the action.
In Apex – if you try to apply the same design strategies that you use in .NET to the Lightning Platform,
you’ll likely encounter problems when you go to test and deploy your solutions. We suggest taking
some time to learn about which design patterns work best in the Lightning Platform world before
you start cranking out the code.
On the Lightning Platform you must have 75% test coverage to deploy your Apex code
to a production org. Not only does having unit tests promote the development of robust
and error-free code, but they’re vital to the stability of the platform, because all tests are
run before every major release. To learn more about unit testing, see An Introduction to
Apex Code Test Methods.
The Lightning Platform has no such thing as a solution or project file. You can create an application,
but it’s not the same as creating a .NET application or assembly.
An application on the Lightning Platform is just a loose collection of components, such as tabs,
reports, dashboards, and pages. Several come built in with your Salesforce org, and in a few
seconds, you can create your own by walking through a point-and-click wizard. You can even
purchase apps created by third-parties on what is known as the AppExchange.
All your code resides and executes in the cloud. There is also no such thing as a config file in the
Lightning Platform world. And unlike ASP.NET MVC, you don’t need to configure routes. You can
create custom settings in Salesforce, but these are added and managed declaratively.
The Apex class library is considerably smaller than the .NET Framework class library, so it’s easier and
faster for you to come up to speed with Apex.
Keep in mind that the Lightning Platform is built with the idea of providing rapid application
development.
However, if you’re looking to build pixel-perfect, custom-coded applications, our Heroku Enterprise
platform provides all the power and features you need.
• Development Tools\ Developer Console - to edit and navigate source code, and it’s also
helpful for debugging and troubleshooting.
• Salesforce CLI (Not in Trailmix\CRM Period PDF)
https://developer.salesforce.com/tools/salesforcecli
The Salesforce CLI is a powerful command line interface that simplifies development and build
automation when working with your Salesforce org. Use it to:
• Aggregate all the tools you need to develop with and perform commands against your
Salesforce org
• Synchronize source to and from scratch orgs
• Create and manage orgs
• Import and export data
• Create and execute tests
• Create and install packages
Handling Security
Identity is handled by the platform. You can control access to data at many different levels,
including object level, record level, and field level. Security is also handled declaratively. In
many cases, security is defined and set up by a Salesforce administrator. As a developer, it’s
important to be aware of how it works. Learn more by checking out the Data
Security module.
Integration
You can integrate with the platform in a number of ways, but you’ll probably use
SOAP and REST the most. You can use them in either direction.
You can create and expose web services using the Apex programming language, as
well as invoke external web services from Apex.
You can also react to incoming email messages and have automated outbound
messages sent when certain events occur.
Salesforce offers both SOAP and REST APIs that provide direct access to the data in
your org. Toolkits that wrap around the APIs are available, so you can use whatever
language you prefer: .NET, Java, PHP, Objective C, Ruby, and JavaScript.
Numerous third-party integration applications are also available on the
AppExchange. Really, just about anything is possible. You can learn more about all
the integration points by completing the Apex Integration module.
The class we’ll create includes the public method sendMail. It includes a private helper
method called inspectResults for inspecting the results of the email send call.
1. From Setup in your Developer org, select Your Name > Developer
Console to open Developer Console.
2. In Developer Console, select File > New > Apex Class.
3. Enter EmailManager as the class name and click OK.
4. Delete the existing code, and insert the following snippet: (And save the class)
Invoke a Method
Because we declared the public sendMail method as static, we can access it without
creating an instance of the class. We can do so easily by using Anonymous Apex in
Developer Console.
1. From Setup, select Your Name > Developer Console to open Developer
Console.
2. Select Debug > Open Execute Anonymous Window.
3. Delete the existing code, and insert the following snippet:
4. Make sure that the Open Log option is selected, and click Execute. A new tab
shows you the execution log.
5. Select the Debug Only option so that you see only the debug statements
displayed in the log. You should see a message telling you that the Email was
sent successfully. You should also receive an email if you entered a valid email
address.
Answer:
To understand how this works, you need to know all the ways Apex code can be
executed on the platform.
Method Description
Database Trigger Invoked for a specific event on a custom or standard object.
Anonymous Apex Code snippets executed on the fly in Dev Console & other tools.
Asynchronous Occurs when executing a future or queueable Apex, running a batch job, or
Apex scheduling Apex to run at a specified interval.
Web Services Code that is exposed via SOAP or REST web services.
Email Services Code that is set up to process inbound email.
Visualforce or Visualforce controllers and Lightning components can execute Apex code
Lightning Pages automatically or when a user initiates an action, such as clicking a button.
Lightning components can also be executed by Lightning processes and flows.
Besides invoking Apex code, actions, such as creating a new task, sending an email,
performing a field update, or sending an outbound message, can all be triggered by one of
the declarative platform features. These actions also run within an execution context.
• Another important consideration is the context of the user executing the Apex code.
By default, Apex executes in system context. Apex code has access to all objects and
fields. Object permissions, field-level security, and sharing rules aren’t applied for the
current user. You can use the with sharing keyword to specify that the sharing rules
for the current user be taken into account for a class. This topic is important, so check
out Using the with sharing or without sharing keywords.
Trigger Essentials
Similar to triggers in SQL Server, Apex database triggers execute programming logic
before or after events to records in Salesforce. When defining the trigger, you can
specify more than one of the following events:
• before insert
• before update
• before delete
• after insert
• after update
• after delete
• after undelete
You only want to resort to using a trigger when you are absolutely sure that the same
thing cannot be accomplished with one of our point-and-click automation tools.
(Flows)
Let’s walk through creating an Apex database trigger that creates an opportunity
when a new account is entered. This trigger calls a method from a handler class, so
we first need to create that.
1. From Setup, select Your Name > Developer Console to open Developer
Console.
2. In Developer Console, select File > New > Apex Class.
3. Enter AccountHandler for the class name and click OK.
4. Delete the existing code, and insert the following snippet: And save the class.
It’s considered a best practice to use only one trigger per object.
So now that we have the handler class, we create the Account trigger.
1. In Developer Console, select File > New > Apex Trigger.
2. Enter AccountTrigger as the name, and select Account as the sObject.
3. Click Submit.
4. Delete the existing code, and insert the following snippet: And save the
Trigger
1. From Setup, select Your Name > Developer Console to open Developer
Console.
2. Select Debug > Open Execute Anonymous Window.
3. Delete the existing code, and insert the following snippet
4. Make sure that the Open Log option is selected and click Execute. A new tab
shows the execution log. Keep it open so that you can examine it carefully.
Notice that the first line in the execution log marks the EXECUTION_STARTED event
and that the last line is the EXECUTION_FINISHED event. Everything in between is the
execution context.
Let’s take a closer look at what happens. A CODE_UNIT_STARTED event marks when
the code from the Execute Anonymous window was kicked off. This line is
highlighted in red in the image below.
The second CODE_UNIT_STARTED line that is highlighted represents when code for
the BeforeInsert event was executed.
You can’t see this in the image, but if you’re following along with your own instance
of Developer Console, scroll down further in the results and look for other instances
of CODE_UNIT_STARTED. You should see at least one more instance representing
when code for the AfterInsert event was executed. If you had created workflow rules
that fired when a new account was created, they too would show up in the execution
log. All this code operates under the same execution context, and thus, is subject to
the same set of governor limits.
When you need to make a callout to a web service or want to offload simple
processing to an asynchronous task, creating a future method could be the way to
go.
@Future Limitations
Although asynchronous calls are sometimes done to avoid limits, you still need to
consider limits. Check out the link concerning Execution Governors and Limits in
Resources.
Another long-used asynchronous tool is the batchable interface. The No. 1 reason to
use it is if you need to process a large number of records. For example, if you want to
clean up or archive up to 50 million records, the batchable interface is your answer.
You can even schedule your batches to run at a particular time.
To use it, your class implements the Database.Batchable interface. You also define
start(), execute(), and finish() methods. You can then invoke a batch class using the
Database.executeBatch method. For example, the following code creates a batchable
class that processes all accounts in an org and then sends an email when it is done.
You could then invoke the batch class using anonymous code such as this:
Batchable Limitations
The batchable interface is great, but as with just about everything, consider its
limitations.
Queueable Apex
Remember all those limitations we talked about? Well, they were causing problems for some
developers, so there was an outcry for a better solution.
Queueable Apex is much easier to implement than Batch Apex. It just doesn’t have those
pesky limitations we talked about. To demonstrate how it works, let’s take the sample code
that used a future method to do a web callout and implement it using Queueable Apex.
• NONE
• ERROR
• WARN
• INFO
• DEBUG
• FINE
• FINER
• FINEST
These levels run from lowest to highest and are cumulative (They Stack) מצטבר. So if
you pick the finest level, you get all messages that are logged as error, warn, info,
and so on. There are also several debug log categories, and the amount of
information logged depends on the log level.
Ok, You’ve heard a lot about limits, but understanding limits are critical to your
success! Each debug log must be 20 MB or smaller. If it exceeds this amount, you
won’t see everything you need. Additionally, each org can retain up to 1,000 MB\1GB
of debug logs. The oldest logs are overwritten.
Because debug logs are your primary way of getting debug information about your
application, you want to make sure to not exceed these limits. If you never see an
error message, you can’t possibly do anything to address it. In the future you’ll learn
about Advanced Apex Debugging and Best Practices for tips on how to avoid these
kinds of issues.
Developer Console has grown quite a bit in the past few releases. One of its more
useful features is the Log Inspector. To see how it works, let’s walk through running
some anonymous code and viewing the results.
1. From Setup, select Your Name > Developer Console to open Developer
Console.
2. Select Debug > Change Log Levels.
3. Click the Add/Change link in General Trace Setting for You.
4. Select INFO as the debug level for all columns.
5. Click Done.
6. Click Done.
7. Select Debug > Perspective Manager.
8. Select All (Predefined) and click Set Default.
9. Click Yes to change this to your default perspective.
10. Close the Developer Console Perspective window.
11. Select Debug > Open Execute Anonymous Window.
12. Delete the existing code, and insert the following snippet:
13. Make sure that Open Log is selected, and click Execute.
14. Select Debug > Switch Perspective > All (Predefined).
15. Examine the results in the Timeline and Executed Units tabs.
16. Under Execution Log, select the Filter option, and enter FINE. Because we set
the debug level to INFO for Apex Code, no results appear.
17. Select Debug > Change Log Levels.
18. Click the Add/Change link in General Trace Setting for You.
19. Change the DebugLevel for ApexCode and Profiling to FINEST.
20. Click Done.
21. Click Done.
22. Select Debug > Open Execute Anonymous Window.
23. Leave the code that is currently there, and click Execute.
24. Under Execution Log, select the Filter option, and enter FINE. The filter search
is case sensitive. You now see "My Fine Debug Message" displayed. You
should also notice a size difference between the two latest logs in the Logs
tab.
Set Checkpoints
Checkpoints are similar to breakpoints in that they reveal a lot of detailed execution
information about a line of code. They just don’t stop execution on that line.
To see how they work, let’s walk through setting a checkpoint on a line of code that
you created in an earlier unit on Understanding Execution Context. If you haven’t
created the handler and trigger code for the AccountTrigger, go back to that unit
and complete that section before continuing.
1. From Setup, select Your Name > Developer Console to open Developer
Console.
2. Select File > Open.
3. Select Classes as the entity type, and AccountHandler as the entity.
4. Click Open.
5. Position your cursor over line 10 in the left margin and click once. A red dot
appears next to the line number.
6. Double-click the latest entry in the Logs panel to open the debug log.
7. Select Debug > Open Execute Anonymous Window.
8. Delete the existing code, and insert the following snippet
1. From Setup, open the Object Manager and click the required Object.
2. In the left sidebar, click Fields & Relationships.
3. Click New.
4. Select Formula
Further Examples
Let’s look at a few more examples. You can create these formulas yourself or simply
read through.
2. If you want to apply a discount to an opportunity amount, you can use the
following formula. In this case, we’re applying a 12% discount and then
rounding the result to two decimal places using the ROUND() function.
The formulas documentation contains numerous examples for many different use
cases. While you’re browsing these examples, keep in mind that many of them
contain advanced concepts that weren’t covered in this unit. Make sure you’re
comfortable with the information presented here before tackling these formulas.
You can perform different types of calculations with roll-up summary fields. You can
count the number of detail records related to a master record, or calculate the sum,
minimum value, or maximum value of a field in the detail records. For example, you
might want:
• A custom account field that calculates the total of all related pending
opportunities.
• A custom order field that sums the unit prices of products that contain a
description you specify.
• There are a few different types of summaries you can use.
Type Description
COUNT Totals the number of related records.
SUM Totals the values in the field you select in the Field to Aggregate option. Only number,
currency, and percent fields are available.
MIN Displays the lowest value of the field you select in the Field to Aggregate option for all
directly related records. Only number, currency, percent, date, and date/time fields are
available.
MAX Displays the highest value of the field you select in the Field to Aggregate option for all
directly related records. Only number, currency, percent, date, and date/time fields are
available.
Examples of Roll-Up Summary Fields
1) Date Opportunity First Created – A roll-up field was created on the Accounts
object. The MIN of all Created Date fields on the Opportunities object
displays the earliest date an opportunity was created related to an
account.
2) Total Price of All Products Related to an Opportunity - A roll-up field was
created on the Opportunities object. Total Price is summarized on the
Opportunity Product object to find the grand total of all products
related to an opportunity
3) Minimum List Price of An Opportunity