Information Technology professional with 25+ years expertise in application design and architecture. I was first introduced to Salesforce during a Gartner Enterprise Architecture summit back in 2008. Salesforce has retired the force.com brand, referring to its platform offerings simply as “Salesforce Platform” An alternative approach is to simply utilize Salesforce as a service. The focus of this publication is to provide options on how to leverage the Salesforce API while side-stepping the use of Salesforce client.
People Mentioned
Companies Mentioned
I was first introduced to Salesforce during a Gartner Enterprise Architecture summit back in 2008. Full transparency here: the primary reason I attended the presentation was the promise of a cool-looking t-shirt that awaited each of us at the end.
The apparel item did not disappoint, as I have a few historical vacation photos which include me wearing that very item. Here is one of my favorites back in 2010 with my son, Eric:
What also did not disappoint me was the technology built on what was then the platform. Those days were a bit confusing because there was and . I quickly understood they were often differentiated as noted below:
" is generally used to refer to the CRM functionality (the sales, service and marketing applications) and is generally used to refer to the underlying platform (the database, code, and UI on which all the apps are built)"
TechTarget also provides the following definition . As the years have passed, Salesforce has retired the brand, referring to its platform offerings simply as “Salesforce Platform.” Still, that t-shirt was cool-looking, right?
A couple of years later, I was still working for the company that sent me to the 2008 Gartner summit. It was then that they decided to embrace the use of Salesforce to track items related to the leasing segment of their business. My basic understanding of Salesforce helped establish custom email routing rules that were passing through internal SendMail gateways. However, that was really my only involvement with the Salesforce ecosystem.
2015 and an Early Publication
Fast-forward seven years to 2015. I was now working as a feature developer, in a full-time corporate role, for a very large automotive conglomerate. After a sprint-worth of feature design that was pretty much introducing a lightweight CRM solution, our team received direction from the corporate office that we should adopt Salesforce instead.
For the next six months, our agile team—clearly in the "" phase—was successful at moving from an existing CRM solution to utilizing Salesforce. This work inspired one of my first publications on :
In fact, since that time I have published several articles about Salesforce, some of which are noted below:
Using Salesforce as a Service
While Salesforce is an excellent experience, introducing another user interface is not always an ideal scenario. In fact, back in 2015, our team felt like we were taking a step backward when we presented the (now called "Salesforce Classic") user interface to consumers who were used to a reactive web design.
Salesforce have evolved their user interface since then, first releasing their proprietary Aura framework, before introducing , an implementation of the web components standard that can run on it's platform, or be used for your own web application. However, there is still the challenge of asking consumers to adopt yet another application into their daily portfolio of technology solutions.
An alternative approach is to simply utilize Salesforce as a service. After all, Salesforce has provided a robust RESTful API for over 10 years now, which allows access to GET, POST, PUT, and DELETE object data as needed.
The focus of this publication is to provide options on how to leverage the Salesforce API while side-stepping the use of the Salesforce client.
Our Scenario
To put things into context for using the Salesforce RESTful API, consider an example where an existing application is already in place. The application provides a majority of the daily functionality required by its users. A major gap, though, is the contact information regarding current and potential clientele.
The feature team recently discovered that all the necessary information exists in Salesforce and there are processes already in place to maintain those contacts. Early indications are that only minor updates will ever be required to a given contact from the existing application.This article will focus on completing a research spike to accomplish the following items:
Create a Salesforce instance for prototyping a solution.
Establish a mechanism to retrieve and update contacts in Salesforce.
Determine how authentication will work.
Validate the functionality using Postman or simple cURL commands.
What You Need To Know
Before we get started, there are a few things that I feel like one should know before heading down this path. You know, that “full transparency” thing that I noted regarding the t-shirt in my introduction.
API Limits Exist
The biggest challenge my feature team faced in 2015 was the number of RESTful API calls that Salesforce allows for every client. Below is a screenshot from the page:
In our case, the two items noted above were a big concern for our team. In hindsight, given the understanding of Salesforce and the ability to cache data, I am confident the resulting Salesforce instance would have not exceeded those limitations. However, I wanted this article to highlight that element for those who are deciding when to utilize this approach.
Authentication Options
Two authentication approaches were considered for this article:
User-based Authentication using OAuth2
Service-based Authentication (also) using OAuth2
The determination of when to use either is directly related to the desire (or need) to make requests as a given user that exists in Salesforce. The alternative is to use a service-based approach, where all of the requests originate from a single user that exists in Salesforce.For this example, the service-based approach will be utilized. As a result, all requests will be completed under the identity of a service-based account in Salesforce.
Integration Options
When connecting to Salesforce, there are several options. Over the last six years, I have been able to utilize the following integration options:
MuleSoft
Heroku Connect
Direct Connect to Salesforce RESTful API via client framework
Spring Boot and Salesforce RESTful API
Using MuleSoft and Heroku Connect would provide connectors and deep insight into the Salesforce data domain. While both are excellent solutions, they do require an additional investment since they are subscription-based.
The direct connect option is possible, but a couple of challenges exist. First, service-based authentication is not likely to be an option—because of challenges with housing the login credentials in a secure manner. Secondly, the client will become heavier as Salesforce data is reformatted for digestible use.
As you might expect (and given my publication history), for this example, I am going to utilize the Spring Boot option and leverage the Salesforce RESTful API. I have a high degree of comfort with this approach.
Creating a Salesforce Instance
The first step is to create a free developer instance of Salesforce. I was able to get started using the following URL:
This led to a simple form that I had to fill out online:
Once the form was submitted, I received the following email at the address noted above:
The contents of this email were quite helpful, as it provides the URL to my developer instance of Salesforce, plus my username.
After verifying my account, I was required to set a password.
Since there will already be contacts in the developer instance, the base setup for Salesforce is complete.
Adding a Connected App
To connect to Salesforce from the Spring Boot service, a new connected app needs to be created.
The following steps were completed using my developer instance of Salesforce:
Navigate to the Setup link
Navigate to Apps → Apps Manager section on the left-hand menu
Select the New Connected App button
Populate the following properties:
Connected App Name to something like “Spring Boot Integration”
API Name (computed value should be fine)
Contact Email (your email address)
API → Enable OAuth Settings = true
Set callback URL to ""
Use OAuth scopes "Access and manage your data (api)" and "Perform requests on your behalf at any time (refresh_token, offline_access)" (for now)
Use "Relax IP restrictions" (for now)
Use "Refresh token is valid until revoked" (for now)
Save the new connected app
Below, is an example of the connected app that I created:
For clarification, below is an example of the OAuth policies I utilized:
Make sure to note the following items for reference later:
Consumer Key value
Consumer Secret value
Configure Network Access
An optional (but recommended) step for the prototyping stage is to create a trusted IP range. This can be used both by your instance of the Salesforce client and for the Spring Boot service as well.
Creating a new trusted IP range simply requires knowing and following the steps listed below.
Obtain your IPv4 address (example: 45.67.100.27)
Navigate to Security → Network Access in Salesforce Setup
Create a new Trusted IP Range which includes your current IP address (I used start address of 45.1.1.1 and 45.255.255.255)
At this point, Salesforce should be set up and ready for use by the Spring Boot service.
Creating the Spring Boot Service
Using the Spring Initializr from IntelliJ IDEA, a new Spring Boot service called salesforce-integration-service was created with the following dependencies:
The methods to retrieve contact information use the @Cacheable annotation to set/retrieve from the cache when possible. For simplicity in this example, when a contact is updated, the entire cache is evicted using the @CacheEvict annotation.
Adding a Logging Interceptor
To provide insight into the performance of the Spring Boot RESTful service, I created a simple logging interceptor to write messages to the console as API calls are processed.
The first step is to establish the LoggingInterceptor class:
@Slf4j
public class LoggingInterceptor implements HandlerInterceptor {
private final String loggedStartTimeKey = "_loggedStartingTime";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
long startTime = System.currentTimeMillis();
request.setAttribute(loggedStartTimeKey, startTime);
log.info("Request Started: method={} path={}", request.getMethod(), request.getRequestURI());
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) {
long loggedStartTime = (long) request.getAttribute(loggedStartTimeKey);
long endTime = System.currentTimeMillis();
long timeTakenMs = endTime - loggedStartTime;
log.info("Request Completed: method={} path={} timeTaken={} (milliseconds)", request.getMethod(), request.getRequestURI(), timeTakenMs);
}
}
Next, I updated the WebConfig class to use the interceptor:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(getLoggingInterceptor()).addPathPatterns("/**"); }
@Bean
public LoggingInterceptor getLoggingInterceptor() {
return new LoggingInterceptor();
}
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
}
@Bean
public CloseableHttpClient closeableHttpClient() {return HttpClients.createDefault();}
}
During the validation section, the log events shown below will be included in the results.
Validating Functionality
With the Spring Boot service ready for use and running, the next step is to validate our expected functionality.
Getting Salesforce Contacts
A list of contacts can be retrieved from Salesforce via the Spring Boot RESTful service using the following cURL command:
curl --location --request GET '//localhost:9999/contacts'
Once submitted, we receive an HTTP 200 (OK) response, with a full list of contacts using the Contact DTO created in Spring Boot:
The initial request took a little over one second to process. To validate that the abstract caching works correctly, I executed the same cURL command again.
This second time, the results were much faster, and there were no calls required to the BearerTokenUtilities or the ContactService:
To retrieve information regarding a single contact from Salesforce, the ID of the contact is required and a similar version of the original cURL command is executed:
curl --location --request GET '//localhost:9999/contacts/0035e000008eXq0AAE'
Upon submission, we receive an HTTP 200 (OK) response, with the single Contact DTO created in Spring Boot provided:
This URI is helpful when only a single contact is required.
Updating Contact Information
In our use case, there is a need to make only minor changes to the contact data in Salesforce. One example is to change the contact’s title value. In order to make an update to the contact’s title attribute, we would use the following cURL command:
Starting in 2021, I have been trying to live the following mission statement, which I feel can apply to any IT professional:
“Focus your time on delivering features/functionality which extends the value of your intellectual property. Leverage frameworks, products, and services for everything else.”
J. Vester
Like my feature team discovered in 2015, Salesforce provides an amazing CRM solution—which met the needs of our project at the time and still meets that corporation's needs today. However, there are times when using the entire Salesforce ecosystem is not preferable.In this article, we created a Spring Boot service example to build upon the well-established Salesforce RESTful API, validating functionality using simple cURL commands. Where possible, the results were cached in order to minimize the use of API calls to the underlying Salesforce API.
If you are interested in the source code used for the Spring Boot service, simply navigate to the following repository on GitLab:
Future articles will provide examples of how to leverage this Spring Boot service for the following JavaScript-based clients:
Svelte
Vue.js
React (React Native)
Angular
Lightning Web Components (outside the Salesforce ecosystem)
These articles will provide high-level examples of how to integrate Salesforce into your current application—without users ever having to log in to Salesforce.