Apex sharing keywords
Do you know how Apex sharing keywords work?
Apex code works based on the closest sharing keyword. This means that for every class you can define different behavior, and even run multiple scenarios from a single start point!
Apex code works based on the closest sharing keyword. This means that for every class you can define different behavior, and even run multiple scenarios from a single start point!
Let’s check an example:
public with sharing class Parent {
public static List<Account> getRecords(String sharingModel) {
switch on sharingModel {
when 'without' {
return WithoutSharing.getRecords();
}
when 'with' {
return WithSharing.getRecords();
}
when 'inherited' {
return InheritedSharing.getRecords();
}
when else {
return DefaultSharing.getRecords();
}
}
}
}Now, we will test how it works:
System.runAs(creator) {
insert creatorRecords;
}
System.runAs(reader) {
insert readerRecords();
}
List<Account> readerList;
Test.startTest();
System.runAs(reader) {
readerList = Parent.getAccounts(SHARING_KEYWORD);
}
Test.stopTest();
Assert.areEqual(EXPECTED_SIZE, readerList.Size());Assumptions: Creator User: 2 records with Reader User: 1 record with private sharing private sharing Results:
TEST NAME OUTCOME MESSAGE RUNTIME (MS)
ParentTest.testDefaultSharing Pass Reader got 3 records 316
ParentTest.testInheritedSharing Pass Reader got 2 records 204
ParentTest.testWithSharing Pass Reader got 2 records 208
ParentTest.testWithoutSharing Pass Reader got 3 records 199Last question, what when a class doesn’t have an access keyword?
public class DefaultSharing {
public static List<Record> getRecords() {
return [SELECT Id, Name FROM Record];
}
}By default, Apex runs in system mode, so the above code runs the same as the class with “without sharing” defined. It is a good practice to always define what sharing class should use!
public without sharing class DefaultSharing {
public static List<Record> getRecords() {
return [SELECT Id, Name FROM Record];
}
}

