I needed to connect a CAP application to a remote oAuth2 client credentials service.
Here is a short recipe 🧑🍳 that describes the steps I made
Ingredients:
package.json
src/rest.cds
src/rest.js
SAP BTP destination service
default-env.json
cds bind destination
Prerequisites:
of course you should have the connection details of the remote service 🤷♂️
For this recipe to work you will need the following connections details (we will come back to these props in step 4):
- Token Service: a url that ends with /token e.g.https://the.oauth.services.url/oauth2/api/v1/token
- OAuth Setup: grant_type = client_credentials
- Client ID: <Your CLIENT ID>
- Client Secret: <Your CLIENT SECRET>
- Service API: <Url link of the remote rest api service you are trying to connect>
Preparations:
1. In package.json
under cds/requires
add your new rest connection, for example:
"cds": {
"requires": {
…
“remoteServiceWithOAuth":{
"kind": "rest",
"credentials": {
"destination": “remoteServiceWithOAuth",
"requestTimeout": 30000
}
}
}
2. Create srv/rest.cds
file:
for each api endpoint you wish to connect you need to create a function or an action described in a cds file (in this example I use rest.cds but you can name it as you wish)
Please note that CAP expects no surprises, you should declare the exact object props and types for each function or action you use.
for example assume that I have function
to GET
todos list, and action
to POST
a new todo item, so my rest.cds
would look like:
service RemoteRestService {
function getTodos() returns array of {
userId: Integer;
id: Integer;
title: String;
completed: Boolean;
};
action createTodo(userId: Integer, title: String, completed: Boolean) returns {
userId: Integer;
id: Integer;
title: String;
completed: Boolean;
};
}
3. Create srv/rest.js
file:
As you probably know our CAP framework uses convention over configuration. So for the implementation part we just need to create the same file name just with .js
extension. for example:
class RemoteRestService extends cds.ApplicationService {
init(){
this.on('getTodos', async (req) =>{
const restApi = await cds.connect.to("remoteServiceWithOAuth") //should match the connection name in step 1
return restApi.tx(req).get("/todos")
})
this.on('createTodo', async (req) =>{
const restApi = await cds.connect.to("remoteServiceWithOAuth")
return restApi.tx(req).get("/todos", req.data)
})
}
}
module.exports = {RemoteRestService}
4. Now you need to login to your SAP BTP CF space
and if you don’t have a destination service bind to your cap service you need to create one. Now create a new destination configuration with the following props:
Name:
remoteServiceWithOAuth (should match the destination in step 1)
Authentication:
OAuth2ClientCredentials
Token Service URL:
(as described in prerequisite part 👆)
URL:
Service API (as described in prerequisite part 👆)
Client ID:
(as described in prerequisite part 👆)
Client Secret:
(as described in prerequisite part 👆)
Token Service User:
in my case I used the same as my Client ID
Token Service Password:
in my case I used the same as my Client Secret
That’s it! Now once you deploy
to your BTP CF space
you should be able to consume you CAP application with the remote rest services 🤘
💡Tip for local development (step 5-6):
In case you want the remote REST to be accessible for your local development as well, you can do it by the following steps:
5. Create /default-env.json
file in the project root
⚠️ – sensitive data, remember to add this file to .gitignore
Copy the value of VCAP_SERVICES to our default-env.json file
How to get your “VCAP_SERVICES” environment variable:
On command line:
cf env <myappname>
Or, by using SAP BTP Cloud cockpit
:
Navigate to the details screen of the deployed app
In the left menu pane click on ‘’Environment Variables”
6. Create a service key for your destination service (from SAP BTP CF
UI or by using cli :
cf create-service-key <yourDestinationService> <YourDestinationServiceKey)
Then run the following CDS bind
command:
cds bind destination --to <yourDestinationService>:<YourDestinationServiceKey>
That’s it 🎉 now you should be able to run: cds watch --profile hybrid
and access your remote destination service
Reference & Credit:
https://blogs.sap.com/2021/07/30/executing-simple-rest-requests-with-sap-cap-applications/ – consume REST from CAP with no authentication