0

I thought this would be a simple thing to find, but all the documentation deals specifically with either creating an Apex web service, or accessing the SF REST API in some general way - but what about accessing a custom Apex web service?

To be more clear, when a developer creates a post request to an Apex web service, what do they include in the headers or body of that post request so that they are able to access the Salesforce endpoint?

For example, one might make a request to a custom SF web service like this:

HttpRequest request = new HttpRequest();
     request.setEndpoint('https://yay.my.salesforce.com/services/apexrest/CreateDOService/v1'));
     request.setMethod('POST');
     request.setHeader('Content-Type', 'application/json;charset=UTF-8');
     request.setHeader(Does some token go here? How do I get it?);
     request.setBody('{"Event":"Thing Returned"}');
HttpResponse response = http.send(request);

What else needs to be included? I see references to OAuth 2.0, SessionIDs, and connected apps in the documentation below, but I can't find any actual examples of code that uses these things. Once I create a connected app for an external application, how do I tell the developer of that application to use the connected app? What kind of code do they need to write?

https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_oauth_and_connected_apps.htm

https://help.salesforce.com/articleView?id=connected_app_create_api_integration.htm

Many thanks for any code examples you could provide.

0

2 Answers 2

1

You authenticate in exactly the same way you do to access the native Salesforce REST API. There are no additional authentication requirements (unless, of course, your code imposes them by for example checking for a Custom Permission).

Specifically, you'd include the Authorization header with the value Bearer <your access token>.

You're free to acquire the access token through any means of establishing an authenticated session in Salesforce: any applicable OAuth flow, or a SOAP login call, or (if calling your own instance) by getting the session Id from the UserInfo class. If you are working in Apex and calling your own instance, a Named Credential can be used to abstract away the authorization details.

To extend your code example:

HttpRequest request = new HttpRequest();
     request.setEndpoint('https://yay.my.salesforce.com/services/apexrest/CreateDOService/v1'));
     request.setMethod('POST');
     request.setHeader('Content-Type', 'application/json;charset=UTF-8');
     request.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
     request.setBody('{"Event":"Thing Returned"}');
HttpResponse response = http.send(request);

Note that you do have to be in a context that offers an API-enabled session Id. You cannot use the session Id in a Lightning Apex controller to make API calls; you must use a Named Credential in that context.

8
  • Thanks for this! A couple questions come to mind: - Is the access token always a "session ID"? - Can any API request use any session ID, even if every login call generates a different session ID? - What is the purpose of creating a "Connected App" in the UI? Is it not necessary? Thanks again, I don't know why I couldn't find a simple example like that in any documentation.
    – number41
    Apr 25, 2020 at 4:54
  • Connected Apps are required for OAuth authentication. If you are building an external application, you should store an access token and refresh token; you should not re-authenticate for every request.
    – David Reed
    Apr 25, 2020 at 14:07
  • Thanks, so in my case, we have an external system that just needs to send SF a message occasionally. It does not need access to SF data. Do we need a Connected App for OAuth authentication? Or can I just generate a session ID and give it to the developer who works on the external system? I’m having a hard time understanding why there are so many different ways of authentication.
    – number41
    Apr 26, 2020 at 0:00
  • Session Ids are not valid forever. If your remote system needs to maintain or reestablish a connection into Salesforce, it needs to implement an appropriate OAuth flow and utilize a refresh token to generate new access tokens. OAuth is complicated, it's true, but there is lots of documentation and many questions and examples throughout SFSE.
    – David Reed
    Apr 26, 2020 at 0:20
  • There are simpler routes that involve storing actual credentials on the remote system (a username and password) but storing actual credentials is a bad practice.
    – David Reed
    Apr 26, 2020 at 0:22
1

To access Salesforce Apex API from the external system , you need to have an access token.At a high level below steps are needed to access apex API.

1) Create a connected app in Salesforce.Connected app is always in the destination system. Here you are trying to call Salesforce API ,so the connected app will be in Salesforce. If you are trying to call some other application from salesforce, another application provider will setup the connected app and provide you the client id and client secret.Refer- https://help.salesforce.com/articleView?id=connected_app_overview.htm&type=5

2) Get the client id and client secret from the connected app and have an integration user setup and make sure this user has access to connected app

3) Generate an access token using client id and client secret and other parameters through one of the ways. Generating an access token will be a post call. Use one of the ways- https://help.salesforce.com/articleView?id=remoteaccess_oauth_flows.htm&type=5

4) Once you have an access token , use it to call salesforce api. Request header should have

request.setHeader('Authorization', 'Bearer '+access_token)

access_token is the token generated from step 3.

Note:-

1) Username-Password is not the recommended way of generating an access token.

2) Client Id and Client secret must not be directly exposed , rather must be kept as an encrypted.

3) It's good to cache an access token and reuse the same access token , before generating a new token, since it counts towards the Total API limit in 24 hours. It is good to check the validity of an access token before generating a new one.

Refer the below link for the same example- https://www.gosquared.com/blog/salesforce-rest-api-integration

Not the answer you're looking for? Browse other questions tagged .