Aura & Visualforce Controllers

Aura (the original Lightning Components framework) calls the same @AuraEnabled methods.

31.1 Aura components

Aura (the original Lightning Components framework) calls the same @AuraEnabled methods. New development should use LWC, but many orgs still maintain Aura.

The component markup declares <aura:component controller="AccountController">.

// accountListController.js (Aura)
({
    init : function(component, event, helper) {
        const action = component.get('c.searchAccounts');
        action.setParams({ searchKey: 'Acme' });
        action.setStorable();                                  // client cache (cacheable methods)
        action.setCallback(this, function(response) {
            if (response.getState() === 'SUCCESS') {
                component.set('v.accounts', response.getReturnValue());
            } else if (response.getState() === 'ERROR') {
                console.error(response.getError()[0].message);
            }
        });
        $A.enqueueAction(action);
    }
})

31.2 Visualforce controllers

Visualforce is the legacy server-rendered page framework, still used for PDFs (renderAs="pdf"), email templates, and older apps.

Built-in per object (standardController="Account"), enforces CRUD/FLS Standard list controller

recordSetVar for lists, uses ApexPages.StandardSetController

Your Apex class (controller="MyController"), runs in system mode

Adds logic to a standard/custom controller (extensions="MyExt")

Visualforce concepts: view state (keep it small; use transient for non-persistent fields), PageReference navigation, ApexPages.currentPage().getParameters(), @RemoteAction for JavaScript remoting, and the Continuation class for long callouts.

public with sharing class AccountSummaryExtension {
    private final Account acct;
    public List<Contact> contacts { get; private set; }

    public AccountSummaryExtension(ApexPages.StandardController stdController) {
        if (!Test.isRunningTest()) stdController.addFields(new List<String>{ 'Name', 'Industry' });
        this.acct = (Account) stdController.getRecord();
        contacts = [SELECT Id, Name, Email FROM Contact WHERE AccountId = :acct.Id WITH USER_MODE];
    }

    public PageReference markHot() {
        acct.Rating = 'Hot';
        update as user acct;
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM, 'Marked as Hot'));
        return null;                                    // stay on the page
    }
}
<apex:page standardController="Account" extensions="AccountSummaryExtension">
    <apex:form>
        <apex:pageMessages />
        <apex:pageBlock title="{!Account.Name}">
            <apex:pageBlockTable value="{!contacts}" var="c">
                <apex:column value="{!c.Name}"/>
                <apex:column value="{!c.Email}"/>
            </apex:pageBlockTable>
            <apex:commandButton value="Mark Hot" action="{!markHot}"/>
        </apex:pageBlock>
    </apex:form>
</apex:page>