TL;DR
- Apex is Salesforce's strongly typed, Java-like language for business logic that declarative tools can't handle cleanly: complex triggers, integrations, async jobs and custom controllers.
- Learn it in this order: SOQL and DML, collections, triggers with a handler framework, async Apex, then tests. The three courses above cover exactly that path.
- The skill that separates juniors from seniors is bulk thinking: every piece of code must work for 200 records as well as for one, inside governor limits.
What the courses cover
Pulled live from the course catalogue — module by module.
- Visualforce
- SOQL
- SOSL
- Data Manipulation Language [DML]
- Collection Framework
- Advanced Apex
- Asynchronous Apex
- Apex Test Framework
- Introduction
- Doing the code coverage when we hit Exceptions
- Code Coverage for Asynchronous Apex
- Doing the code coverage by respecting the User context
- Assert Class and Assert Statements
- Doing the code coverage for Apex Classes making REST API Callout
- Doing the code coverage for REST API Apex Classes
- Doing the code coverage for SOAP API Classes
- Others
To learn Apex properly, you need four things in this order: SOQL and DML against the Salesforce data model, collections, triggers built on a handler framework, and asynchronous Apex, with a test class for every one of them. That's the path the three courses above take. Everything is typed live in a real org, governor-limit errors included, and I explain why each line exists.
Apex is Salesforce's strongly typed, object-oriented language. It runs on Salesforce's servers, inside a multi-tenant platform, and that one fact shapes almost every rule you'll learn.
What Apex is and when you actually need it
On a real project, I reach for Apex when declarative tools stop being the clean option:
- Complex trigger logic. Rules that touch several objects, need careful ordering, or must run identically for data loads and API updates.
- Integrations. Calling external REST services, exposing your own REST endpoints, and processing platform events.
- Large data volumes. Batch and Queueable jobs that process records far beyond what a single transaction allows.
- Back ends for Lightning Web Components.
@AuraEnabledmethods that query, aggregate and save data for your UI. - Reusable services called from Flow through invocable methods.
If a record-triggered flow can do it simply and maintainably, use the flow. Apex is for when it can't, or when the flow would become a tangle that nobody can debug.
Prerequisites
- The admin fundamentals. Objects, relationships, the sharing model and validation rules. The free Salesforce admin course covers them.
- Basic programming. Variables, conditionals, loops, functions and classes in any language. You don't need Java specifically.
- A Developer Edition org and VS Code with the Salesforce extensions. See the Salesforce DX and VS Code guide.
What you'll be able to build afterwards
- Triggers that delegate to handler classes, process 200 records as easily as one and don't recurse
- SOQL that uses relationships, aggregates and bind variables, with user-mode security
- Queueable, Batch and scheduled jobs for work that doesn't fit in one transaction
- Test classes that assert behaviour, not just coverage
- The Apex side of an LWC feature, ready for code review
A hands-on example: a bulkified trigger handler
Requirement: when an account's billing city changes, update the mailing city on all its contacts. Here's how I'd write it.
trigger AccountTrigger on Account (after update) {
AccountTriggerHandler.syncMailingCity(Trigger.new, Trigger.oldMap);
}
public with sharing class AccountTriggerHandler {
public static void syncMailingCity(List<Account> newAccounts, Map<Id, Account> oldMap) {
Map<Id, Account> changed = new Map<Id, Account>();
for (Account acc : newAccounts) {
if (acc.BillingCity != oldMap.get(acc.Id).BillingCity) {
changed.put(acc.Id, acc);
}
}
if (changed.isEmpty()) {
return;
}
List<Contact> contacts = [
SELECT Id, AccountId
FROM Contact
WHERE AccountId IN :changed.keySet()
WITH USER_MODE
];
for (Contact con : contacts) {
con.MailingCity = changed.get(con.AccountId).BillingCity;
}
update as user contacts;
}
}
Why it's written this way:
- The trigger contains no logic. It hands off to a class you can test, reuse and reason about.
- It filters first. Only accounts whose billing city actually changed go into the map, so an unrelated update does no work at all.
- One query, one DML statement, whatever the batch size. Whether 1 or 200 accounts arrive, the code runs one SOQL query and one update. There's no SOQL or DML inside a loop.
- The map does the lookup.
changed.get(con.AccountId)finds each contact's account in memory instead of querying again. with sharing,WITH USER_MODEandupdate as usermake the class respect sharing, object permissions and field-level security for the running user.
Then comes the follow-up I always ask in the course: what if one account has 15,000 contacts? A single transaction can only update 10,000 rows with DML, so you'd move the contact update into a Queueable job. Knowing where your design breaks is part of the design.
Common mistakes beginners make
- SOQL or DML inside a loop. It works in a demo with one record and fails at the first data load. The full reasoning is in Apex bulkification explained.
- Logic in the trigger body. It can't be reused or tested in isolation, and multiple triggers on the same object run in an order you don't control. Use one trigger per object with a handler.
- A static Boolean to stop recursion. When more than 200 records are saved, triggers run in chunks of 200 within the same transaction, and a static "already ran" flag silently skips every chunk after the first. Track processed record IDs instead, or compare old and new values.
- Ignoring sharing and field-level security. Declare
with sharingunless you have a documented reason not to, and use user-mode queries and DML where the running user's access should apply. - Hard-coded IDs. Record type IDs, user IDs and queue IDs differ between orgs. Look them up by developer name.
- Testing with one record. Your tests should insert at least 200 records to prove the code is bulk-safe. See Apex testing.
- Swallowing exceptions. An empty
catchblock hides the bug and leaves data half-updated. Handle it, or let it fail loudly.
How Apex connects to the other topics
- Testing isn't optional: Salesforce requires 75% code coverage across your org's Apex to deploy to production, and the Apex testing guide explains how to go beyond the number.
- Lightning Web Components call Apex for anything Lightning Data Service can't do. Continue with LWC.
- Integration is advanced Apex: callouts, Named Credentials, platform events and REST services. That's Salesforce integration.
- For the overall sequence, follow the Salesforce developer roadmap. For interviews, drill Apex interview questions, Apex trigger questions, SOQL questions and async Apex questions.
Who should skip this
- Skip it if you're an admin with no plans to write code. Learn Flows deeply instead. That's the higher-value skill for your role.
- Skip the basics if you already ship Apex and write bulk-safe triggers with tests by habit. Jump to the integration course or the async sections.
- Don't skip it if you've only ever copied Apex from forums. Code that works for one record and code that survives production are different things.
Not sure about the teaching style? Apex Triggers Framework 101 is free. Watch it end to end before you subscribe, because there are no refunds.
Apex Triggers Framework 101
8 episodes · 0.5 hours
Salesforce Development (Visualforce & Apex)
47 episodes · 5.6 hours · 8 modules
Apex Test Fest
40 episodes · 5 hours · 9 modules
Learn it by building it
Every course, every code repository, the discussion group and certificates of completion — one subscription.
Frequently asked questions
How long does it take to learn Apex?
If you already program in another language and know the Salesforce data model, you can write useful triggers within a few weeks. Writing bulk-safe, secure, well-tested Apex that passes code review takes months of building real features.
Do I need to know Java before learning Apex?
No, but any object-oriented language helps. Apex syntax is close to Java, so variables, classes, loops and collections will feel familiar if you know Java, C# or similar.
Should I learn Apex or Flow first?
Learn the admin basics and enough Flow to know what it does well, then Apex. Good developers know when not to write code, and you can only judge that if you know Flow.
Is the Apex Triggers course free?
Yes. Apex Triggers Framework 101 is free. It's a good way to judge the teaching before you subscribe for the full development and testing courses.
Is Visualforce still worth learning?
Only enough to maintain existing pages. New UI work should use Lightning Web Components. The Apex, SOQL and DML you learn alongside Visualforce apply everywhere.
Keep going
Career roadmap
Salesforce Developer Roadmap 2026
Topic guide
Learn Apex Testing: Write Test Classes That Prove Your Code Works
Blog
Apex Bulkification Explained: From 'Too Many SOQL Queries: 101' to Bulk-Safe Code
Interview questions
Apex Interview Questions and Answers (2026)
Interview questions
Apex Trigger Interview Questions and Answers (2026)
Blog
Apex Test Classes: Stop Chasing 75% Coverage