Hands-on challenge solution for Platform Developer I Certification Maintenance (Winter ’21)
Insights to PD1 Winter’21 Hands on.
- Field- and Object-Level Security
- Safe Navigation Operator
Enforce Field- and Object-Level Security
The Security.stripInaccessible
method allows developers to remove all fields from the records that the running user does not have access to. This make the application simply remove fields than throwing fail exceptions.
The stripInaccesible
method checks the source records for fields that don’t meet the field- and object-level security check for the current user and creates a return list of sObjects. The return list is identical to the source records, except that fields inaccessible to the current user are removed.
Resources:
Apex Developer Guide: Enforce Security with the stripInaccessible Method.
Apex Developer Guide: Security Class.
Apex Developer Guide: SObjectAccessDecision Class.
Apex Developer Guide: AccessType Enum.
Use the Safe Navigation Operator to Avoid Null Pointer Exceptions
Use the safe navigation operator (?.
) to replace explicit, sequential checks for null references. This new operator short-circuits expressions that attempt to operate on a null value and returns null instead of throwing a NullPointerException.
If the left-hand side of the chain expression evaluates to null, the right-hand side is not evaluated. Use the safe navigation operator (?.
) in method, variable, and property chaining. The part of the expression that is not evaluated can include variable references, method references, or array expressions.
Resources:
Salesforce: Apex Developer Guide: Security Class
Salesforce Help: Winter ’21 Release Notes: Use the Safe Navigation Operator to Avoid Null Pointer Exceptions
@RestResource(urlMapping = '/apexSecurityRest')
global with sharing class ApexSecurityRest {
@HttpGet
global static Contact doGet() {
Id recordId = RestContext.request.params.get('id');
Contact result;
if (recordId == null) {
throw new FunctionalException('Id parameter is required');
}
List <Contact> results = [SELECT Id, Name, Title, Top_Secret__c, Account.Name FROM Contact WHERE Id =: recordId];
SObjectAccessDecision securityDecision = Security.stripInaccessible(AccessType.READABLE, results); //Security.StripInaccessible
if (! results.isEmpty()) {
result = (Contact)securityDecision?.getRecords()[0]; //safe navigation
result.Description = result?.Account?.Name; //safe navigation
}
return result;
}
public class FunctionalException extends Exception {}
}