I may need to make many @RestResource
Apex classes run either with sharing
or without sharing
where that option is selected at runtime.
But this approach (that I am using at present):
/**
* Allow code to run "with sharing" or "without sharing" based on configuration.
*/
public inherited sharing class Sharing {
public interface Executable {
Object execute(Object[] args);
}
// With
private with sharing class WithSharing {
public Object execute(Executable executable, Object[] args) {
return executable.execute(args);
}
}
// Without
private without sharing class WithoutSharing {
public Object execute(Executable executable, Object[] args) {
return executable.execute(args);
}
}
//
// Execute the code with or without sharing based on this documentation...
//
// Both inner classes and outer classes can be declared as with sharing.
// The sharing setting applies to all code contained in the class,
// including initialization code, constructors, and methods.
// Inner classes do not inherit the sharing setting from their container class.
//
public static Object apply(Executable executable, Object[] args) {
// TODO from config
Boolean withSharing = false;
if (withSharing) return new WithSharing().execute(executable, args);
else return new WithoutSharing().execute(executable, args);
}
// No-args
public static Object apply(Executable executable) {
return apply(executable, new Object[] {});
}
}
is quite ugly to add to the many classes (that have static
entry points) e.g.:
@RestResource(urlMapping='...')
global inherited sharing class MyRest {
@HttpPost
global static Result post() {
return (Result) Sharing.apply(new Executable());
}
private inherited sharing class Executable implements Sharing.Executable {
public Object execute() {
return postWithSharingApplied();
}
}
// The content of the original post method
private static Result postWithSharingApplied() {
...
}
...
}
Is there a cleaner way to do this?
PS
A follow-up question is Inherited sharing question in nested inner classes.
PPS
A key point is that the class containing the business logic MyRest
above must not be declared as with sharing
or without sharing
so is best declared as inherited sharing
. (I originally didn't realize this.) This makes each business logic method also have inherited sharing
.
The key sentences from the documentation about this are:
The sharing setting of the class where the method is defined is applied, not of the class where the method is called
and:
A class declared as inherited sharing runs as without sharing only when explicitly called from an already established without sharing context.