Preface – This post is part of the UI5 Integration Programs series.
Table of Contents
What is the concept of Destination in SAP BTP?
In SAP Business Technology Platform (SAP BTP), a destination is a configuration object that defines the connection parameters for accessing a service or system from SAP BTP.
A destination is used as a way to define the communication settings for a service and to ensure secure access to the service. The destination defines the target URL of the service, the credentials that are used to access the service, and other configuration properties such as the communication protocol, message format, and security settings.
Destinations can be used to access a variety of services such as Cloud Foundry applications, APIs hosted on SAP API Business Hub, and data sources like databases or SAP S/4HANA systems.
In SAP BTP, you can manage destinations through the Destination service in the SAP Cloud Platform cockpit, where you can create, update, or delete destinations as needed.
What are the different ways that we can create a Destination in SAP BTP?
There are several ways to create a destination in SAP Business Technology Platform (SAP BTP):
- SAP Cloud Platform Cockpit: You can use the SAP Cloud Platform cockpit to create and manage destinations. This is the recommended method for creating destinations in SAP BTP, as it provides a user-friendly interface and ensures that the destinations are properly secured and configured.
- API: You can use the SAP Cloud Platform Destination API to programmatically create and manage destinations. This is useful when you need to automate the creation and management of destinations or when you need to integrate the creation and management of destinations into a custom application.
- SAP Cloud Platform Connectivity Service: You can use the SAP Cloud Platform Connectivity Service to create destinations, which is particularly useful when connecting to external systems from SAP BTP.
- SAP Cloud Platform Extension Factory: You can use the SAP Cloud Platform Extension Factory to create destinations for services hosted within your SAP BTP landscape. This is useful when you need to access services that are not directly available through the SAP Cloud Platform cockpit.
Regardless of the method used to create a destination, it is important to properly secure the destination by defining the appropriate authentication and authorization settings. This ensures that the destination can be used securely to access the target service or system from SAP BTP.
In this article, we will focus on the below integrations:
- Neo Destination in SAP UI5
- Cloud Foundry Destination in SAP UI5
- Destination as a Service in SAP UI5
Creating a Destination in SAP BTP
1. Visit your BTP Platform by visiting here: https://account.hana.ondemand.com/#/home/welcome
2. Create a new Destination for your API, in our case, we have created one for YouTube and another for Northwind.
Northwind OData
How to Consume Neo Destination in SAP UI5
To consume a destination in SAP UI5 from the Neo environment, you need to perform the following steps:
- Create a destination: You need to create a destination in the SAP Business Technology Platform (SAP BTP) using one of the methods described in my previous answer. Make sure the destination is properly configured and secured, just like the way we have done above. You can read more here.
- Add the destination to your SAP UI5 application in Neo.json File: You need to add the destination to your SAP UI5 application by creating a binding in the manifest.json file of your application. The binding provides the necessary information to connect to the destination, such as the URL and authentication credentials. Add the below section within “routes” array of neo-app.json
{ "path": "/destination/youtube", "target": { "type": "destination", "name": "Test", "entryPath": "/destination/youtube" }, "description": "Test Destination" }, { "path": "/destinations/northwind", "target": { "type": "destination", "name": "northwind" }, "description": "Northwind OData Service" }
- Consume the destination from Controller File: In your SAP UI5 code, you can consume the destination by using the SAPUI5 framework’s OData model. You can create an instance of the OData model and pass it the URL of the destination as well as any additional configuration parameters, such as authentication credentials.
Here is an example of how you can consume a destination in SAP UI5:
// Get the URL of the destination from the binding var sServiceUrl = this.getOwnerComponent().getModel("destination").sServiceUrl; // Create an instance of the OData model var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl, { useBatch: true }); // Set the OData model on the view this.getView().setModel(oModel);
In this example, the destination URL is obtained from the binding created in the manifest.json file of the application. The OData model is then created and set on the view, allowing you to access the data provided by the destination in your SAP UI5 code.
For YouTube, we can directly consume the URL even in view, like this:
<html:iframe height="100%" width="100%" src="/destination/youtube"/>
For Northwind, we have added the given code in:
manifest.json
"dataSources": { "NorthwindModel": { "uri": "/destinations/northwind/V2/Northwind/Northwind.svc/", "type": "OData", "settings": { "odataVersion": "2.0" } } }
And also set the model using the above dataSoruce
"": { "type": "sap.ui.model.odata.v2.ODataModel", "settings": { "defaultOperationMode": "Server", "defaultBindingMode": "OneWay", "defaultCountMode": "Request" }, "dataSource": "NorthwindModel", "preload": true },
Controller.js
sap.ui.define([ "sap/ui/core/mvc/Controller" ], function (Controller) { "use strict"; return Controller.extend("Test.Test.controller.Main", { onInit: function () { var that = this; var oOdataModel = this.getOwnerComponent().getModel(); oOdataModel.setUseBatch(false); oOdataModel.read("/Products", { success: function (oData) { that.getView().setModel(new sap.ui.model.json.JSONModel(oData), "customerModel"); } }); } }); });
View.xml
<mvc:View controllerName="Test.Test.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:table="sap.ui.table"> <Shell id="shell"> <App id="app"> <pages> <Page id="page" title="Consuming Neo Destination in SAP UI5"> <content> <table:Table id="customerTable" selectionMode="Single" rows="{customerModel>/results}" enableColumnReordering="false"> <!--columns for Product Name--> <table:columns> <table:Column width="20%"> <table:label> <Label text="Product Name"/> </table:label> <table:template> <Text text="{customerModel>ProductName}"/> </table:template> </table:Column> </table:columns> </table:Table> </content> </Page> </pages> </App> </Shell> </mvc:View>
Output For Table Binding
How to Consume Cloud Foundry Destination in SAP UI5
To consume a Cloud Foundry destination in SAP UI5, you can follow these steps:
- Create a destination: First, you need to create a destination in SAP Business Technology Platform (SAP BTP) for the Cloud Foundry service you want to access. You can do this through the SAP Cloud Platform cockpit or by using the SAP Cloud Platform Destination API. Make sure the destination is properly configured and secured. You can read more here.
- Add the destination to your SAP UI5 application: You need to add the destination to your SAP UI5 application by creating a binding in the manifest.json file of your application. The binding provides the necessary information to connect to the destination, such as the URL and authentication credentials.
Add the following codes:
xs-app.json
{ "authenticationType": "none", "csrfProtection": false, "source": "^/Northwind/(.*)$", "destination": "Northwind", "target": "$1" }
OData services and Models in Manifest:
"dataSources": { "mainService": { "uri": "/V2/Northwind/Northwind.svc/", "type": "OData", "settings": { "annotations": [], "localUri": "localService/metadata.xml", "odataVersion": "2.0" } } }
"": { "dataSource": "mainService", "preload": true, "settings": {} }
ui5.yaml
# yaml-language-server: $schema=https://sap.github.io/ui5-tooling/schema/ui5.yaml.json specVersion: "2.5" metadata: name: cfxsapp type: application server: customMiddleware: - name: fiori-tools-proxy afterMiddleware: compression configuration: ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted ui5: path: - /resources - /test-resources url: https://ui5.sap.com backend: - path: /V2 url: https://services.odata.org destination: Northwind - name: fiori-tools-appreload afterMiddleware: compression configuration: port: 35729 path: webapp delay: 300 - name: fiori-tools-preview afterMiddleware: fiori-tools-appreload configuration: component: cfxsapp ui5Theme: sap_horizon
- Consume the destination: In your SAP UI5 code, you can consume the destination by using the SAPUI5 framework’s OData model. You can create an instance of the OData model and pass it the URL of the destination as well as any additional configuration parameters, such as authentication credentials.
View.xml<mvc:View controllerName="cfxsapp.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m"> <Page id="page" title="{i18n>title}"> <content> <List items="{/Products}"> <StandardListItem title="{ProductName}"/> </List> </content> </Page> </mvc:View>
Output
A good article for step-by-step setup reference: Creating a sample SAPUI5 application with destination in Cloud Foundry environment | SAP Blogs
How to Consume a Destination as a Service in MTA or CAPM App
To consume a destination as a service in an MTA or CAPM (Cloud Application Programming Model) application in the SAP Business Technology Platform (SAP BTP), you need to follow these steps:
- Create a destination: First, you need to create a destination in SAP BTP for the service you want to access. You can do this through the SAP Cloud Platform cockpit or by using the SAP Cloud Platform Destination API. Make sure the destination is properly configured and secured.
Step 01: Visit SAP HANA on demand portal here.
Step 02: Enter into your Global account and click “Service Market Place” as shown below:
Step 03: Search for “Destination”
Step 04: Click three dots to create a new instance
Step 05: Enter details and provide a name for your destination and click next
Step 06: Once created, you can see your destination within your instance
Step 07: Click your instance and click “Manage Instance” to open Dashboard of your destination service
Step 08: Create a new Destination as you would have created within the BTP Destination section
- Bind the destination to your MTA or CAPM application: To bind the destination to your MTA or CAPM application, you need to add a destination service to your
mta.yaml
file for MTA applications or to yourpackage.json
file for CAPM applications. The service definition provides the necessary information to connect to the destination, such as the URL and authentication credentials. - Consume the destination: In your application code, you can consume the destination by using the appropriate client library for the service you are accessing. For example, if you are accessing an OData service, you can use the SAPUI5 framework’s OData model to connect to the service.
Here is an example of how you can consume a destination as a service in an MTA application:
# mta.yaml _schema-version: "2.1" ID: my-mta version: 0.0.1 modules: - name: my-module type: nodejs path: my-module requires: - name: my-destination-service group: destinations properties: name: my-destination-service resources: - name: my-destination-service type: org.cloudfoundry.managed-service properties: service: destination service-plan: lite parameters: name: my-destination url: "<destination-url>" forwardAuthToken: true apiEndpoint: "<destination-api-endpoint>"
In this example, the destination is bound to the MTA application as a service by adding a resources
section to the mta.yaml
file. The service definition includes the properties necessary to connect to the destination, such as the destination URL, API endpoint, and whether to forward the authentication token.
For our usecase, we have this code in MTA.yaml
_schema-version: '3.2' ID: mtaApp version: 0.0.1 modules: - name: mtaapp-approuter type: approuter.nodejs path: mtaapp-approuter requires: - name: mtaApp_html_repo_runtime group: destinations properties: forwardAuthToken: false name: ui5 url: 'https://ui5.sap.com' parameters: disk-quota: 256M memory: 256M - name: mtaApp_ui_deployer type: com.sap.application.content path: . requires: - name: mtaApp_html_repo_host parameters: content-target: true build-parameters: build-result: resources requires: - artifacts: - cfapp.zip name: cfapp target-path: resources/ - name: cfapp type: html5 path: cfapp build-parameters: build-result: dist builder: custom commands: - npm install - 'npm run build:cf' supported-platforms: [] resources: - name: mtaApp_html_repo_runtime type: org.cloudfoundry.managed-service parameters: service: html5-apps-repo service-plan: app-runtime - name: mtaApp_html_repo_host type: org.cloudfoundry.managed-service parameters: service: html5-apps-repo service-plan: app-host - name: NorthwindTest type: org.cloudfoundry.managed-service parameters: service: destination service-plan: lite parameters: deploy_mode: html5-repo
In the end the code is added for Destination.
Once the destination is bound as a service, you can consume it in your code by using the appropriate client library for the service you are accessing. For example, if you are accessing an OData service, you can use the SAPUI5 framework’s OData model to connect to the service.
I am trying to call a product list API below to get the list of products in a JSON format. I found the API link from the network tab while accessing the SAP API Business HUB.
https://DOMAIN/api/1.0/categories?$expand=products($top=10)
I can get a response while calling the API directly from the browser. However, I’m getting a CORS error when calling it using JavaScript.
ERROR:
Access to fetch at ‘https://DOMAIN/api/1.0/categories?$expand=products($top=10)’ from origin ‘https://APPSERVICE1.azurewebsites.net’ has been blocked by CORS policy: The value of the ‘Access-Control-Allow-Credentials’ header in the response is ” which must be ‘true’ when the request’s credentials mode is ‘include’.
Also, there are some preflight requests that are being called while calling this API from the browser.
Is there a way to access this API?
Do I need to add an access token to call this API?
Is there any additional permission that needs to be granted?
Should my appservice domain be added on SAP side?
Thank you for your help.
To solve the CORS issue, add your url in BTP Destination. Then access the destination in your javascript.
Watch this: https://www.youtube.com/watch?v=e9pYZ4adkWk&ab_channel=MyProjectIdeas
More relevant Destination videos are there on the YouTube channel.