Skip to Content
Technical Articles

CAP: Consume External Service – Part 3

In my previous blog posts, I discussed how CAP handles the consumption of external service. Overall, it’s elegant and simple to consume external service especially with the fact that CAP handles the complexity of consuming destination service configuration in SCP. However, there are limitations to which CAP can handle external services, i.e. it can handle only OData services.

In this blog post, I will show how you can break away from this limitation and handle the consumption of external service by doing the handling on your own. It is worth noting here as well, that there are certain scenarios on consuming an OData service that CAP framework might not work very well, and hence, you still need to resort on workaround solutions, like for example the issue that was raised in this Q&A.

 

 

Prerequisites


  • SAP Cloud Platform for the Cloud Foundry environment
  • SAP Business Application Studio / Visual Studio Code

 

Blog Post Series


 

Introduction – Limit Break


Compared to Part 1 and Part 2 of this blog post series, where we use the CAP way of consuming external services, here, we will identify the CAP limitations and I will provide a way to break away on those limitations.

Whenever I come across a scenario where I break away on the limitations (which happens a lot of times), I’m reminded of my first encounter with a full-length RPG game – Final Fantasy VIII. Simply because of the Limit Break skill called Lion Heart which (I guess) meant to be overpowered. I have put a reference video below, although the graphics might not be so appealing now, it was a class of its own back then.

Okay, enough with the digression!

While working with external service consumption, I’ve come across a number of scenarios where the CAP framework doesn’t work well. Here they are (with additional items where it is a known limitation of CAP):

  • Some operation didn’t work well when using Connectivity Proxy (SAP Cloud Connector)
  • Can’t specify custom header information
  • Can’t handle complex querries for OData Services
  • Non-OData services are not supported (OpenAPI/RESTful web services)

For these scenarios, the advice is to handle the service consumption on your own. This means that you need to handle the service consumption in the Node.js way. It will be good if you are already familiar with developing in Node.js, but how about if you want to continue using Destination Service so that you don’t hardcode the service definitions in your logic? Also, how about the convenience of testing the service locally without much change when deploying the service to SCP?

These are the questions I had when I was thinking of handling the service consumption on my own. I was thinking that there should be some node module that can help with consuming destination service in SCP. And as a matter of fact, there is a node module called sap-cf-destconn. This node module helps in retrieving the destination and connectivity configuration from SCP. Okay, this helped to answer my first question, but how about the convenience of testing the service locally? Unfortunately, for this scenario, there’s no solution I can find. So what I did is I created my own solution — the cdse node module.

 

CDSE Node Module


To answer my own questions, I have implemented my own logic to reuse the CDS configuration for external service, and cater to the local testing and SCP configuration scenario. Also, I made sure that the implementation is kept simple and adopting the fluent API concept of CAP. Therefore, maintaining the simplicity and elegance that we know from the CAP framework. And of course, some good things are meant to be shared, so I’ve published the solution to npmjs.com. It was my first time to publish a node module. Refer the link below for the cdse node module:

https://www.npmjs.com/package/cdse

Kindly refer to the documentation on how to install and how to use the module.

 

Demo of service consumption


The CAP base project for this demo is the solution from the previous blog post – Consume External Service – Part 2. The source code is provided through the link below:

https://github.com/jcailan/cap-samples/tree/blog-es-part2

Note:

If you didn’t go through part 2 of this blog post series, then you should refer to the Setup Destination Configuration section of Consume External Service – Part 2 before you proceed with the steps below.

  • 1. Once the source code is loaded in your development IDE, start installing the node module by executing the command:
> npm install cdse
  • 2. Replace the implementation of the custom handler file catalog-service.js, with the logic below:
const cds = require('@sap/cds');
const cdse = require('cdse');

module.exports = cds.service.impl(async function() {
	const { Products } = this.entities;
	const service = await cdse.connect.to('NorthWind');
	this.on('READ', Products, async () => {
		const result = await service.run({ url: 'Products' });
		return result.value;
	});
});

Compared to the previous code, the new implementation of external service consumption is still looking neat and clean, but at the same time offers more flexibility for calling the service, because it is using axios parameter pattern.

Axios is the node module used by the CAP framework itself to consume external services.

That’s it! We’re done and it can’t be any more simple than that.

 

Testing the service


To show that the CDSE module caters both local testing and SCP destination configuration options, let’s put it to test.

  • 1. Let’s first test the service locally. To do that, change the configuration of the external service to point to NorthWind service URL directly:
	"cds": {
		"requires": {
			"NorthWind": {
				"kind": "odata",
				"model": "srv/external/NorthWind",
				"credentials": {
					"url": "https://services.odata.org/Experimental/OData/OData.svc"
				}
			}
		}
	}
  • 2. Test the service, and you should get the results below:

  • 3. Next, let’s test using the SCP Destination Configuration. To do that, change the CDS configuration to point to the NorthWind destination.
	"cds": {
		"requires": {
			"NorthWind": {
				"kind": "odata",
				"model": "srv/external/NorthWind",
				"credentials": {
					"destination": "NorthWind"
				}
			}
		}
	}
  • 4. Test the service locally and it should give you the same results. Additionally, you can build and deploy the CAP project to SCP and test using the deployed version, and should still give you the same results.

 

Closing


There you have it! A simple way of consuming external service for scenarios that you are not able to use CAP due to some constraints or limitations. The good thing about the CDSE module is that it is able to read the CDS configuration from package.json file and adapt the runtime conditions for both local and SCP testing.

Just take note that while CDSE extends the capability of external service consumption in the CAP Model, it also has its own limitation. Feel free to post a comment here or raise an issue in GitHub if you find any issues. I hope that it can help you in your CAP-based projects.

 

 

~~~~~~~~~~~~~~~~

Appreciate it if you have any comments, suggestions, or questions. Cheers!~

2 Comments
You must be Logged on to comment or reply to a post.