Why the @AuraEnabled annotation is your bridge to Apex
In my experience, developers sometimes treat this annotation as a “set it and forget it” piece of code. But it is actually doing a lot of heavy lifting under the hood. It tells the Lightning framework that a specific method is safe and available for client-side calls.You will need to use it in a few specific scenarios:- When you need to fetch data for an LWC using a wire service.
- When you are calling an Apex method imperatively from a JS controller.
- When you want to use Apex properties directly in your component markup.
One thing that trips people up is that these methods must always be public or global and static. I have seen teams waste hours debugging “method not found” errors only to realize they forgot the static keyword. Apex cannot instantiate your class automatically when a component calls it, so that static marker is non-negotiable.

Getting the most out of the @AuraEnabled annotation with caching
Now, here is where it gets interesting. If you are just pulling data and not making any changes to records, you should always usecacheable=true. I cannot stress this enough. It tells Salesforce to store the results on the client side, which makes your UI feel much faster.
public with sharing class AccountController {
@AuraEnabled(cacheable=true)
public static List<Account> getTopAccounts() {
return [SELECT Id, Name, Industry FROM Account LIMIT 10];
}
}
But be careful. If your method needs to perform a DML operation – like inserting a contact or updating a case – you must leave cacheable=true out. If you try to perform DML in a cacheable method, Salesforce will throw an error faster than you can blink. It is a common mistake, but a quick one to fix.
Pro Tip: If you are building complex UIs, you might want to learn how to do communication between Lightning web components so you aren’t making redundant Apex calls from five different places.
Security and Sharing
Look, we have all been tempted to skip security checks when we are in a rush. But when you use the @AuraEnabled annotation, you are opening a door to your server. Always usewith sharing on your classes to respect the org’s sharing rules.And remember, Apex does not automatically check if a user has permission to see a specific field. You should still perform manual CRUD and FLS checks inside your methods. It is better to write a few extra lines of code now than to deal with a data leak later.How to call your code in LWC
So how do you actually use this in your JavaScript? You have two main paths. You can use the@wire decorator for a reactive approach, or you can call the method imperatively.
// The wired way (requires cacheable=true)
@wire(getTopAccounts)
accounts;
// The imperative way (works for anything)
handleLoad() {
getTopAccounts()
.then(result => { this.accounts = result; })
.catch(error => { console.error(error); });
}
I usually prefer @wire because it handles the provisioning for you. But if you need a call to happen only when a user clicks a button, imperative is the way to go. Just make sure your return types are serializable – stick to primitives, sObjects, or simple lists and maps.
Key Takeaways
- The @AuraEnabled annotation is required for any Apex method called by LWC or Aura.
- Methods must be static and public or global.
- Use
cacheable=truefor read-only operations to boost performance. - Never use caching if your method performs DML or changes data.
- Always enforce security with
with sharingand manual FLS checks.








8 Comments