Storing Environment Specific Configuration Values for your Apex Code in Salesforce

If you are writing Apex code for your Salesforce orgs, you’ll likely run into a situation where you want to refer to certain pieces of data that you simply don’t want to hard-code within your classes and methods. Pieces of information like API keys, endpoint URLs. Your code may be interfacing with an external API and while in development and testing, you may have a developer API key and a test endpoint for use in your sandbox. When your code is promoted to production, you want these callouts to be made against the production equivalents of those external APIs. If you have a C# / .NET Core development background like I do, I’m talking about something analogous to an appsettings.json file. I came across such a situation and my research lead to a few options:

  • Named Credentials: If your need is specifically in relation to reaching out to an external endpoint that you authenticate with in some sort of an industry standard (e.g., OAuth2), do checkout Named Credentials. This approach is quite prescriptive in its implementation but if your use-case matches, then this is certainly a very good option.
  • Custom Settings: If your need is more “custom” then Custom Settings may be for you. It is quite a powerful feature, allowing you to meet a variety of use-cases. Below, we’ll look at a simple application for a simple use-case: the ability to store a set of key/value pairs that can then be referenced at runtime, from within your Apex code.

Hard-Coded Configuration Values

Consider the piece of code, below:

public class CustomSettingsDemo {
    @future (callout=true)
    public static void callRemoteApi() {
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://my-remote-endpoint/go/do/stuff');            
		request.setMethod('POST');
		request.setBody('{"mySuperSecretToken":"my-hard-coded-token-goes-here"}');
                            
		HttpResponse response = new HttpResponse();
		Http http = new Http();
		response = http.send(request);
        System.debug(response.getBody());
	}
}

In my example code above, there are two pieces of configuration values that are currently hardcoded within:

  • My API endpoint URL
  • mySuperSecretToken

How can I use Custom Settings to specify those values outside of code so that I can keep them different in different environments (instances)?

Create a Custom Setting

You can access Custom Settings from within Setup:

Custom Settings screen from Setup

Click the “New” button to create a new Custom Setting:

Create new Custom Setting definition
Next, define one or more fields. For our example, we’ll create two fields, one to store the endpoint URL and another to store our “super secret token”:
I have defined these two fields as two Text fields. Make note of the API names as these are the identifiers we’ll use in our Apex code to access these. Next, click the “Manage” button to specify values for these:
You can then add one ore more sets of values for this custom setting. The first one becomes the default for your Organization. You can add more, as needed, segment them by different Profiles or Users:
adding a set of values to the custom setting

Accessing Custom Settings in Apex Code

Now, the fun part – accessing these values, at runtime, from within your Apex code. Here’s a refactored version of my earlier example code, now using the Custom Setting that we created above:

public class CustomSettingsDemo {
    @future (callout=true)
    public static void callRemoteApi() {
        // Get an instance of my custom setting
        MySuperFancyApiSettings__c apiSettings = MySuperFancyApiSettings__c.getInstance();        
        
        HttpRequest request = new HttpRequest();
        
        // Get the API URL from the Custom Setting field
        request.setEndpoint(apiSettings.Endpoint_Url__c);            
		request.setMethod('POST');
        
        // Get the super secret token from Custom Setting too.
		request.setBody('{"mySuperSecretToken":"' + apiSettings.Super_Secret_Token__c + '"}');
                            
		HttpResponse response = new HttpResponse();
		Http http = new Http();
		response = http.send(request);
        System.debug(response.getBody());        
	}
}

Parting Thoughts

We only looked at simple use case of Custom Settings available in Salesforce. You can also utilize this in the context of packages that you transport from org to org or even look at the related notion of Custom Metadata Types.

Leave a Comment

Your email address will not be published. Required fields are marked *