What I learned from my first Salesforce product development project
At Horizontal, we pride ourselves on being experience forward—that means we continually push ourselves to adopt new technologies that stay ahead of your customers’ needs. This fast-paced environment means we’re fortunate to work with innovative thinkers and that we get to take on new projects.Recently, I had the opportunity to take on my first custom Salesforce development project, building a custom product for AppExchange. Like any IT project, as we outlined custom features and flows for solving problems, our requirements became complex. While virtually anything is possible with code, that doesn’t mean customization is more important than best practices. In reality, when you throw best practices out the window, you often get this:As it turns out, coding for Salesforce is no different than developing on other platforms. Throughout this project, I had a crash course in custom development for Salesforce. But building on Salesforce doesn’t have to be a huge learning curve. Here’s the best practices I’ve learned that’ll get you building on Salesforce in no time.
Author Notes:
As you start, be sure to document the intent of the code—what are you trying to achieve? What is the desired functionality?
Define Sharing Rules for Apex Classes:
After writing author notes, you’ll need to define sharing rules for Apex classes. Salesforce Platform relies heavily on data sharing rules—each object can have unique CRUD permissions for different user profiles. These unique permissions are enforced for all standard controllers. However, when using a custom Apex class, the built-in profile permissions and field-level security settings are not enforced.At default, an Apex class has the ability to read and update all data with the organization; thus, developers must define sharing rules for the Apex class, so they do not inadvertently expose data that is hidden on all standard controllers.Classes should explicitly declare with sharing rules when possible. For example:
Do Not Include Sensitive Information in Debug Statements:
Debug statements can be invaluable for diagnosing issues in the functionality of an application, but they should not publicly disclose sensitive or overly detailed information. This includes access tokens, user ids, passwords etc.
Revealing detailed and private information in debug statements makes your code base vulnerable to hackers by revealing potential attack vectors.
When Building Managed Packages, Avoid Hardcoding:
Like any development project, deployments can be tricky. When you factor in that you’re coding a package that will be installed in disparate orgs, things get even trickier. When deploying from environment to another, softcoding allows references to dynamically call on record IDs. By avoiding hardcoding, you’re ensuring that references still work as record IDs change from org to org.This is doubly important when building packages. As a package gets installed in a customer’s org, you can’t control how they name IDs, so softcoding these references ensures your package will display the correct records no matter which org it’s installed in.Here is a sample that hardcodes the record type IDs that are used in an conditional statement:
This format will result in the correct functionality within a specific org, but once the code package is installed in a different org, the correct record would only display if this exact record ID was also in the new org.However, if you softcode an ID, the code package should reference the correct ID in the new org. In a Salesforce Lightning component, this is how the code should be written:
This snippet shows how the Apex code accesses the record ID parameter in the Lightning component:
Another way to avoid hardcoding is to use custom labels for any static data. This will reduce the complexity of any code change and will allow develoipers to modify alert/success message without modifying or redeploying code.Below are couple of examples of how you can access data from custom label using Apex and Lightning Components.Accessing value from custom label in Apex:
Accessing value from custom label in Lightning:
User Permission & Field-Level Security Enforcement:
In general, standard object and field permissions and are configured via profiles and permission sets. When building a custom application, the same level of user permissions (CRUD) and field-level security (FLS) should be enforced. Maintaining CRUD and FLS settings across custom objects will provide consistency in data access and user experience.Use this syntax to verify if user has access to select record from a custom object:
Use this syntax to verify if user has access to update a record from a custom object:
Use this syntax to verify if user has access to add a new record within a custom object:
Secure Storage of Sensitive Data
If your application copies and stores sensitive data that originated from your or your customer’s Salesforce org you need to follow specific security protocols.When storing Salesforce credentials like OAuth access tokens or SSO session information, follow these industry best practices:
- Never store Salesforce passwords in your code package (or anywhere outside of the original Salesforce instance)
- Ensure protected custom settings, named credentials, and other security measures are replicated within your application
Custom settings allow developers to build custom data sets that include data points from third party applications. This is helpful when building data sets from multiple applications like Marketing Cloud and Sales Cloud.Setting the visibility of the Custom Setting Definition to “Protected” and including it in a managed package ensures that it’s only accessible programmatically via Apex code that exists within your package.To allow for updates to user IDs or passwords, create a Visualforce page or Lightning component that accepts the input but does not render on a page. This will allow Admins to access protected without exposing this to other users. This will allow Admins to access protected data without exposing this to other users.
A simple form UI will allow you to input user data:
These best practices will help you avoid common pitfalls with custom Salesforce development. As you take on your first projects, don’t forget to frequent the Trailblazer Community—if you have a questions, someone has probably asked it as well, so search here for answers.Happy coding!