Wiring Apex & Lightning Data Service
Connect components to Salesforce data using the wire service, Apex methods, and Lightning Data Service.
Wiring Apex & Lightning Data Service
A UI is only useful with real data, and LWC offers two main ways to read and write Salesforce records: Lightning Data Service (LDS) and Apex. LDS is the preferred default for single-record operations because it's declarative, cache-aware, and keeps records in sync across components without you writing server code. Apex is for anything LDS can't express — complex queries, multi-object logic, and custom server processing.
The wire service is how components reactively consume data. You decorate a property or function with @wire, point it at an adapter, and LWC calls it, caches the result, and re-invokes it when reactive parameters change. LDS provides wire adapters like getRecord and getObjectInfo from the lightning/ui*Api modules, while the base components lightning-record-form, lightning-record-edit-form, and lightning-record-view-form give you create/edit/view UI with almost no code.
import { LightningElement, api, wire } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import NAME_FIELD from '@salesforce/schema/Account.Name';
import INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
// Apex, wired reactively
import getContacts from '@salesforce/apex/AccountController.getContacts';
export default class AccountPanel extends LightningElement {
@api recordId;
@wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD, INDUSTRY_FIELD] })
account;
@wire(getContacts, { accountId: '$recordId' })
contacts;
get accountName() {
return getFieldValue(this.account.data, NAME_FIELD);
}
}
Note the '$recordId' syntax: prefixing a parameter with $ makes it reactive, so when recordId changes the wire re-runs automatically. Importing fields from @salesforce/schema gives compile-time safety and makes Salesforce aware of the dependency. To call Apex, the method must be @AuraEnabled; mark it (cacheable=true) to use it with @wire for read-only, cacheable data, or call it imperatively (returning a Promise) when you need to invoke it on demand, such as on a button click, or when writing data.
Choosing between them: use LDS for single-record read/create/update/delete because it caches and shares records automatically; use cacheable Apex with @wire for read-only lists and queries; use imperative Apex for writes and actions triggered by user interaction. Always handle both the data and error branches a wire provides. With data flowing, the next lesson adds the platform niceties users expect — navigation, toasts, and error handling.