Learn What’s New in Apex for Platform Developers

Learning Objectives

After completing this unit, you’ll be able to:

  • Manage Apex trigger subscriptions to custom platform events through the user interface.
  • Ensure code coverage requirements prior to releasing an unlocked package.
  • Create, configure, and send custom notifications directly from Apex code.
  • Make Apex callouts after publishing platform event messages.

Salesforce Certification

If you hold the Salesforce Platform Developer I credential, keep in mind that you need to complete this module by the due date to maintain your certification. Another important part of maintaining your credential is ensuring your Trailhead and Webassessor accounts are linked.

Interested in learning more about getting certified? Check out the Salesforce Platform Developer I credential.

Salesforce introduced a ton of great feature enhancements. Let’s take a look at some of the more important ones for this release.

Note: While anyone can earn this badge, this module is designed for those who hold the Salesforce Certified Platform Developer I certification. 

Enable Field- and Object-Level Permissions Checking Using WITH SECURITY_ENFORCED in SOQL Queries

What’s new?

In Spring ’20, SOQL queries using WITH SECURITY_ENFORCED became generally available. Use the WITH SECURITY_ENFORCED clause to enable field and object level security permissions checking for SOQL SELECT queries in Apex code. The WITH SECURITY_ENFORCED clause causes the runtime to fail queries that have any FLS/CRUD violations in their SELECT clause.

How does it work?

Use the WITH SECURITY_ENFORCED clause to enable checking for field- and object-level security permissions on SOQL SELECT queries. 

If fields or objects referenced in the SELECT clause using WITH SECURITY_ENFORCED are inaccessible to the user, the query throws an exception indicating insufficient permissions and no data is returned. 


List<Contact> contactsWithSecrets = [SELECT name, social_security_number__c

Polymorphic Fields

There is a new restriction while querying polymorphic lookup fields using WITH SECURITY_ENFORCED. Polymorphic lookup fields are relationship fields that can point to more than one entity.

  • Traversing a polymorphic field’s relationship is not supported in queries using WITH SECURITY_ENFORCED.
  • Using TYPEOF expressions with an ELSE clause is not supported in queries using WITH SECURITY_ENFORCED.
  • The Owner, CreatedBy, and LastModifiedBy polymorphic lookup fields are exempt from this restriction, and do allow polymorphic relationship traversal.

We recommend using WITH SECURITY_ENFORCED in Apex classes or triggers with an API version 45.0 or later.

Manage Your Platform Event Trigger Subscriptions from the User Interface

What’s new?

You can now suspend and resume Apex trigger subscriptions to a custom platform event through the user interface. Resume a suspended trigger subscription where it left off, from the earliest available event message, without losing any events published during the suspension. To bypass event messages that are causing errors or are no longer needed, resume the subscription from the tip, starting from new event messages. 

Prior to Winter ’21, you could only deactivate a trigger to suspend the subscription. And when reactivated, the subscription resumed from the tip, missing any unprocessed event messages.

How does it work?

To access the platform event detail page, in Setup, enter Platform Events in the Quick Find box, click Platform Events, and then click the platform event. To manage a trigger subscription, click Manage next to the Apex trigger listed under Subscriptions in the platform event detail page.

List of subscribers for the platform event

On the subscription detail page, you can manage the subscription.

Manage a subscription on the subscription detail page

After you suspend a subscription,  you can resume it.

Resume a subscription on the subscription detail page.

Code Coverage Enforcement for Unlocked Packages

What’s new?

Meeting code coverage requirements helps validate that the Apex code in your unlocked packages has adequate test coverage. Starting in Winter ’21, the Apex code must meet a minimum 75% code coverage requirement before you can promote and release an unlocked package.

Package versions created in Winter ’21 and later that don’t meet this code coverage can be installed only in scratch orgs and sandboxes. Unlocked package versions that were promoted to the released state before Winter ’21 aren’t subject to the code coverage requirements.

How does it work?

To compute code coverage using Salesforce CLI, use the --codecoverage parameter when you run the force:package:version:create command. 

To compute code coverage using the Tooling API, set the CalculateCodeCoverage field to true on the Package2VersionCreateRequest object when you create a package version.

Package version creation can take longer to complete when code coverage is being computed, so consider when to include the code coverage parameter in the development cycle.

Send Custom Notifications from Apex

What’s new?

Use Messaging.CustomNotification to create, configure, and send custom notifications directly from Apex code, such as a trigger. Avoid making HTTP callouts to the API from Apex to create custom notifications. Use the new Apex CustomNotification support directly.

It requires fewer lines of code, and avoids API callout and authentication complexity. It’s also more efficient, which is especially helpful when you’re sending notifications from triggers, or sending many notifications.

How does it work?

Using the Messaging.CustomNotification class to create and send custom notifications from Apex is straightforward. 

CustomNotification allows two approaches to create and configure a custom notification.

  1. Create an instance with the default constructor, and then set notification attributes using the various setter methods.
  2. Create an instance and configure parameters at the same time by specifying the notification parameters when calling the constructor.

Once the custom notification is configured, call send() to send the notification.

 The code snippets in the example below show the first approach.


Create a new instance of CustomNotification using the default constructor.

Messaging.CustomNotification notification = new Messaging.CustomNotification();

Configure the required contents, type, and target for the notification.

notification.setTitle('Apex Custom Notification');
notification.setBody('These notifications are coming from inside Apex code.');

Once the custom notification is configured, call send() to send the notification.


For more details, see, Apex Developer’s Guide: CustomNotification class.

Make Apex Callouts After Publishing Platform Event Messages

What’s new? 

With Winter ’21, you can now make Apex callouts after publishing event messages for events configured with the Publish Immediately behavior. Previously, after publishing such events, you couldn’t make callouts from any Apex code. Events published immediately have a new limit, which is separate from the Apex DML statement limit. 

How does it work?

Events configured with the Publish Immediately behavior are published when the call executes and do not depend on the successful completion of the transaction. These events are used for tracking and logging purposes.

With this change, they aren't considered part of the transaction's DML operations, and therefore no longer prevent Apex callouts from being performed after publishing. They count against a new, separate publishing limit of 150 EventBus.publish() calls. This change doesn’t apply to events configured with the Publish After Commit behavior, whose publishing is considered part of the transaction’s DML operations. The publishing of these events still counts against the Apex DML statement limit. And you can still make Apex callouts after publishing.

To track the limit usage of calls for immediate publishing, use:

Limits.getPublishImmediateDML()  Returns the number of EventBus.publish calls that have been made for platform events configured to publish immediately.

Limits.getLimitPublishImmediateDML() Returns the total number of EventBus.publish statements that can be called for platform events configured to publish immediately.


Keep learning for
Sign up for an account to continue.
What’s in it for you?
  • Get personalized recommendations for your career goals
  • Practice your skills with hands-on challenges and quizzes
  • Track and share your progress with employers
  • Connect to mentorship and career opportunities