Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
mariusobert
Developer Advocate
Developer Advocate
In this blog post, I will briefly explain why there are ‘destinations’ in SAP BTP, Cloud Foundry. I will also show some hands-on examples of how to consume them.

Leveraging existing services and data sources is the core of each cloud-based business application out there. Connecting applications to those destinations is a very crucial element of your application and should be done the right way. SAP BTP recognized the importance of this element and offers with the destination service a scalable solution in the Cloud Foundry Environment.

To keep this post as simple as possible, I won’t dive into the SAP Cloud Connector or the SAP Connectivity Service, which is a proxy service to redirect requests to on-premise systems (I recommend this blog post if you’re interested in this scenario).

Updates:

19th Nov 2020 - Refresh GIFs

29th Jan 2021: Rebranding to SAP BTP

9th Jan 2021: Add video tutorial to test destinations

Why do I need destinations?


I think all of us agree that it would be easiest to hardcode the destination information into the codebase. But this (rookie) mistake has several issues, just to name a few:

  1. Re-usability


You would need to copy and paste the same information into several modules/apps when you want to re-use it (=> Antipattern)


  1. Standardized form


Closely related to the re-usability aspect, you need to come up with a standardized format (e.g. do you prefer the properties ‘protocol’, ‘hostname’, ‘port’ or would you rather combine them to ‘URL’?). It’s crucial to enforce this format across all destinations


  1. Sensitive information in the codebase


Never ever (ever!) add sensitive information, such as passwords, to your code! I think I don’t need to explain this one


  1. Need to handle various authentication strategies


Authentication strategies vary access different destinations types and you need to implement each single one


  1. Integration with development tools


Dev tools (like code generators) have virtually no use if they cannot access supporting information

How can I make sure my destinations are set up correctly?


I recorded a short video tutorial that you can follow to make sure your destination is working as expected. Do you know your destination is already accessible? Then jump ahead to the next section.


Watch the video on YouTube



How does this translate to the “Cloud Foundry world”?


The previous section did not only show that information about the endpoints should be stored centrally, but it also showed that there is a need for “business logic” to consume it.

In general, applications shouldn’t be hardwired to resources (like text files or database systems), but be rather coupled loosely to them. Backing services are the best practice to couple resources to applications running in Cloud Foundry environments. Therefore, SAP encapsulates the necessary business logic and the persistence layer for those tasks and makes it easy to consume as a backing service (Destination service).

Your application can access the destinations via a so-called (Destination) service instance.

Using the destinations-service in the backend


There are three steps to enable a backend application to access destinations

  1. Enter the information for the destination


I recommend that you enter them on the subaccount level in the Cloud Foundry environment (it’s also possible to add them on the service instance level).




  1. Create a destinations service instance


This service is able to read and transmit the information you stored in the previous step it securely.




  1. Create an xsuaa service instance


This service issues a JWT token to authenticate to the destinations service instance.

Same as the previous step, just filter the marketplace for “trust” instead.

My colleague Matthieu Pelatan has described this process of retrieving the destination information very detailed in a mini-blog-series (Part 1, Part 2, Part 3). Therefore, I would like to keep this section rather short and simply list the necessary steps here:

  1. Read required the environment variables

  2. Use the retrieved values to request a JWT access token (for the destinations service instance) from the UAA

  3. Get the destination details from the destination service instance

  4. Request the resource behind your destination!



 

The official documentation contains nice code samples for Java and your terminal (curl), so instead, I thought I'd supply some code in JavaScript and Python.

Node.js [JavaScript]


This snippet uses the npm package request, which can be substituted with a module of your choice.

 
const request = require('request');
const cfenv = require('cfenv');

/*********************************************************************
*************** Step 1: Read the environment variables ***************
*********************************************************************/
const oServices = cfenv.getAppEnv().getServices();
const uaa_service = cfenv.getAppEnv().getService('uaa_service');
const dest_service = cfenv.getAppEnv().getService('destination_service');
const sUaaCredentials = dest_service.credentials.clientid + ':' + dest_service.credentials.clientsecret;

const sDestinationName = 'scp';
const sEndpoint = '/secure/';

/*********************************************************************
**** Step 2: Request a JWT token to access the destination service ***
*********************************************************************/
const post_options = {
url: uaa_service.credentials.url + '/oauth/token',
method: 'POST',
headers: {
'Authorization': 'Basic ' + Buffer.from(sUaaCredentials).toString('base64'),
'Content-type': 'application/x-www-form-urlencoded'
},
form: {
'client_id': dest_service.credentials.clientid,
'grant_type': 'client_credentials'
}
}

request(post_options, (err, res, data) => {
if (res.statusCode === 200) {

/*************************************************************
*** Step 3: Search your destination in the destination service ***
*************************************************************/
const token = JSON.parse(data).access_token;
const get_options = {
url: dest_service.credentials.uri + '/destination-configuration/v1/destinations/' + sDestinationName,
headers: {
'Authorization': 'Bearer ' + token
}
}

request(get_options, (err, res, data) => {

/*********************************************************
********* Step 4: Access the destination securely *******
*********************************************************/
const oDestination = JSON.parse(data);
const token = oDestination.authTokens[0];

const options = {
method: 'GET',
url: oDestination.destinationConfiguration.URL + sEndpoint,
headers: {
'Authorization': `${token.type} ${token.value}`
}
};

request(options).on('data', (s) => {
console.log(s.toString())
});
});
}
});

Python


SAP recently announced that the Python runtime is officially supported now! So, I would like to take this as an occasion to include a python script here:
from cfenv import AppEnv
import requests
import base64


######################################################################
############### Step 1: Read the environment variables ###############
######################################################################

env = AppEnv()
uaa_service = env.get_service(name='uaa_service')
dest_service = env.get_service(name='destination_service')
sUaaCredentials = dest_service.credentials["clientid"] + ':' + dest_service.credentials["clientsecret"]
sDestinationName = 'scp'

######################################################################
#### Step 2: Request a JWT token to access the destination service ###
######################################################################

headers = {'Authorization': 'Basic '+base64.b64encode(sUaaCredentials), 'content-type': 'application/x-www-form-urlencoded'}
form = [('client_id', dest_service.credentials["clientid"] ), ('grant_type', 'client_credentials')]

r = requests.post(uaa_service.credentials["url"] + '/oauth/token', data=form, headers=headers)

######################################################################
####### Step 3: Search your destination in the destination service #######
######################################################################

token = r.json()["access_token"]
headers= { 'Authorization': 'Bearer ' + token }

r = requests.get(dest_service.credentials["uri"] + '/destination-configuration/v1/destinations/'+sDestinationName, headers=headers)

######################################################################
############### Step 4: Access the destination securely ###############
######################################################################

destination = r.json()
token = destination["authTokens"][0]
headers= { 'Authorization': token["type"] + ' ' + token["value"] }

r = requests.get(destination["destinationConfiguration"]["URL"] + '/secure/', headers=headers)
print(r.text)

Please note that you need to declare the modules "request" and "cfenv" to your app via a requirements.txt file before deploying the code.

 

Using the destination service in the frontend (= SAPUI5 web apps)


Apart from the reasons above, there is one additional reason why you want to have a destination service for web apps:

Same Origin Policy

I’m sure every web dev out there cursed this mechanism at least once in his/her life. For the “lucky” ones of you who didn’t have to deal with SOP before: It is a security mechanism of your browser that basically blocks all requests your client-side script sends to any web server, except the webserver which delivered this script.

The most common workaround is sending a request to your web server, which proxies the request to the final destination. With the SAP Application Router, on the other side, you don’t need to bother at all! The router knows how to access the destination out-of-box. You don’t need to request a JWT token from the XSUAA service instance and you don’t need to request the destination information from the destinations-service. You don’t even have to implement the authentication strategy. SAP Application Router takes care of all that for you. 



Here’s what you have to do in the SAPUI5 application:

 

  1. Enter the information for the destination


I recommend that you enter them on the subaccount level in the Cloud Foundry environment (it’s also possible to add them on the service instance level).


 

 

  1. The SAP Business Application Studio should create those resources and bindings by default. Make sure both services are defined ("resources" section) and bound to the app ("requires" section) in the mta.yml file:



resources:
- name: uaa_service
parameters:
path: ./xs-security.json
service-plan: application
service: xsuaa
type: org.cloudfoundry.managed-service

- name: destination_service
parameters:
service-plan: lite
service: destination
type: org.cloudfoundry.managed-service



  1. Add the route to the destination in the file xs-app.json. This descriptor file tells the web server how the requests need to be proxied to the respective destination:



"routes": [{
"source": "^/scp/(.*)",
"target": "/$1",
"destination": "scp"
}...



  1. Call endpoint from the application



$.get('/scp/secure').then((sMsg)=>{alert(sMsg)});


Conclusion


There are many good reasons why you should use destinations in the Cloud Foundry, ABAP, and Kubernetes environment, such as preventing the use of anti-patterns, storing your credentials in a safe place (in general just to make your life easier). At first sight, the process of retrieving those destinations in your application might seem confusing. I hope this article could shed some light on this process and prove that’s it’s actually quite simple.
120 Comments
Hi Marius,

"sapui5" is HTML5 app and "sacweb" is my app router.

Anyways, I will go through that tutorial.

Thanks:)
0 Kudos
Hi Marius,

 

I want to read all destinations available in my subaccount and show the details in a ui5 application in CF. Is this possible?

 

Regards,

Tapishnu
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
Hi,

 

it is possible from the backend when you communicate directly with the destination service. In this case, you need a backend proxy that fetches the data and returns it to the frontend.

https://api.sap.com/api/SAP_CP_CF_Connectivity_Destination/resource
rbhuva
Participant
0 Kudos
Hi Marius,

 

Very Informative Blog post!

 

I want to use destination service in my local project which has node.js module and SAPUI5 module. I Created service key in destination service and using it i created user provided service with tag destination. It is working fine for Node modules but, for sapui5 module it is using approuter and somehow approuter is not fetching the details from user provided service.

 

Do you know anything we could do here which can help approuter to use destination service using user provided service.

 

Thanks,

Rajdeep Bhuva
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
Hi Rajdeep,

is the destination also defined in the xs-app.json configuration of the approuter? You might be able to find some hints in the log of the approuter when you call the route (that points to the destination).

 

You could also check if the coding itself is alright you deploy the application to CF and bind it to the destination service instance.
rbhuva
Participant
Hi Marius,

I am running application outside SAP CF so destination service is not available. I was trying to use credentials of destination service of SAP CF for my local project.

Finally i achieved it by settings VCAP_SERVICES variable before starting approuter.

Thanks,

Rajdeep Bhuva
p619793
Active Participant
0 Kudos
Nicely explained. I have a question. When should we choose SAP Cloud Platform Connectivity destination vs. destination service instance?

Best regards,

Sumit
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
Can you add more details about the services you are referring to? I don't think there are two different types of services.
p619793
Active Participant
0 Kudos

Please see the screenshot below (1 vs. 2)..

mariusobert
Developer Advocate
Developer Advocate
Both are the same service. In the main screen (1), you can create new service instances that can later be bound to a CF app. Each service instance contains its own destinations which are only accessible by bound applications.

The side panel (2) allows you to configure destinations on the subaccount level. These destinations have a larger scope and are available to apps that are bound to ANY service instance.
p619793
Active Participant
0 Kudos
Thanks for explanation. So the only difference is the 'scope' as far as the bound apps are concerned.
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
Yes, both user interfaces belong to the same service. The scope of the destination will vary depending on the UI you used to enter it.
0 Kudos
Hi mariusobert

I need advice in applying this technique in webIDE to open external url in new window with few url parameters and one of the parameters is redirect url.

Any tips on how to achieve the opening of new window without using hardcoded url, that would also take into account additional url parameters?

 

Thank you!!

Shan
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
You can use the destination service to avoid hard-coded URLs in your app, yes.

I'm not sure if I understand the other parts of your question. The Web IDE is a development environment and cannot open URLs in new tabs.

Can you please explain what kind of an app you're building?
0 Kudos
Haha, sorry for not being clear, my english maybe not so good.

I have an UI5 app, developed as MTA with HTML5 Modules. and in this app I need to open new window, with command (window.open or iframe), but the url for this needs to contain several url parameters.

So my question how and where the parameters can be indicated? in CF Destination definition or in webIDE while calling the destination.

 

Thanks!

Shanir
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
I think I got it now 🙂

In either case, I'd use the following JS snippet to open a new window.
window.open(myURL)

I would say it depends on how often the links change. If that only happens every few months, I'd probably hard-code it and update the entire web app if the link changes.
If you want to be more agile, I recommend that a backend service send this URL to your UI5 app. This backend component can then read the URL from the destination service (or a database). UI apps (independent of the framework) cannot directly consume the destination service - only via an approuter (which is a backend component).
0 Kudos
Ok, let me see if I understand this.

If we have MTA app built in webIDE with UI5 Module that utilizes ABAP in Cloud as a backend oData service - there is no way in webIDE to directly consume Destination from CF that holds the url?

When deploying the MTA I can see in CF Space that for the application the approuter is running and has service binding to abap in cloud.

So the way in this case to avoid no-hardcoded-url would be what?

 

Thanks a lot!
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
I wouldn't mention the Web IDE (or any other IDE) in this context. This is only a tool for building web app but the tool itself should not and does not consume data from any destination.

 
0 Kudos
Yes, sure! I don't understand why are you saying things about webIDE being a tool that doesn't consume destination itself? This is not at all my question, I was asking to how to code a line in webIDE for the app to connect to CF destination with url params.
let me ilustrate it, maybe better:


coding in webIDE


so in this case I am asking hot to configure CF destination and coding in webIDE - to not write hardcoded url, but utilize the destination.

 

Hope it is now better understandable.

Thanks!
TimC
Associate
Associate
0 Kudos
Hi Marius

Hopefully a quick question around the best way to connect an SAPUI5 app (standalone approuter deployed in cf) to a node.js "microservice" I have created which has its own approuter.  I have bound both applications to the same xsuaa service instance.  I wanted to keep the front-end separate from the backend node.js application.

The node.js app is using the standard SAP middleware to authenticate user access - works fine if I enter the URL into the browser (will redirect to logon and then check scopes) and then respond with JSON content.

However, I am struggling to work out the best way to connect my SAPUI5 app to this API I have created.  I have tried a destination (both as an environment variable in mta.yaml and a destination set-up in the SCP cockpit but it doesn't seem to work - keep getting a 401 and the API approuter doesn't forward on the request.  I am not sure if this the best method to build a deploy the API and then connect to it from the front-end app.

Hopefully this makes sense !

Many thanks

Tim

 

 

 
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
Hi Tim,

that sounds like you don't use the right authentication type of the destination. You need to choose one to exchange the auth token of approuter 1 to approuter 2. I'm not an expert here so I can't give you more specific instructions, sorry.

In general, I would recommend that one approuter should be enough. CAP apps also provide their server functionality without an approuter and you only need it when the app is combined with a frontend and human user interaction. I understand that there could be some special reasons to have multiple app routers - I just wanted to say it's not the most straight forward option.
TimC
Associate
Associate
Hi Marius

Thanks for the update - it makes sense now that I don't need 2 approuters - it seems to go into a loop of requesting authentication between the 2 approuters.   I've just amended the destination definition in mta.yml to point directly to the application 'microservice' URI (rather than the approuter) and connects fine and returns the JSON.  Just need to check that the scopes work ok now!

Many thanks

 
former_member601204
Discoverer
0 Kudos
Hi javispain , vobu ,

 

Was that pull request created finally to be able to add in the header that "x-csrf-token"?

I don't see that feature it in the repository so I'm calling a SAP Gateway OnPremise service and gives me the error of validation of CSRF Token 😞 ...

Thanks in advance

Diego

 
vobu
Active Contributor
0 Kudos
unfortunately javispain hasn't found the time (yet?) to do the bespoken PR/change. Probably you wanna take over? 😉
Hi Volker,

My apologies, i was so busy and i couldn't change. This is the consultancy life 🙂

In addition, I think we need to update more things... because packages "request-promise" and "request" are deprecated.

Now, I'm working in migrate all to "node-fetch" library.
vobu
Active Contributor
0 Kudos
hi, no sweat, that's how it is 🙂

might also look into "axios" or "got" as alternative to node-fetch.

looking fwd to the PR, v.
0 Kudos
Hi Marius,

The screen below is taken during debugging mode. I have mapped the destination instances to my local build via .env file. When trying to consume GW services via destination through cloud connector, i receive an TCP IP error message, how do i work around this?

I have tested the same on cloud foundry, and the same is unable to call the GW services from my nodejs app. Can you advise further on this.


CF Destination (backend)


 

Ramon
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
Hi Ramon,

I'm not sure what the issue is here and it is not directly related to the generic content of the post. There could be multiple reasons why it doesn't work.
You could try to use this destination in an approuter to make sure it's working in the first place (before trying to use it in your project).

 

Regards,

Marius
jalf1991
Explorer

hi mariusobert

 

Thanks for this blog!.

 

Marius in this moment I am trying to consume a destination from my SAPUI5 app , but when I test the service consume, i am gettin a 404 not found message like service repsonse.

 

this is my xs-app.json config:

{

  "welcomeFile": "/index.html",
  "authenticationMethod": "route",
  "logout": {
    "logoutEndpoint": "/do/logout"
  },
  "routes": [
    {
      "source": "^(.*)$",
      "target": "$1",
      "service": "html5-apps-repo-rt",
      "authenticationType": "xsuaa"
    },{
      "source": "^/confiar/(.*)$",
      "target": "/$1",
      "destination": "confiar"
}
  ]
}

 

My bind services resources mta.yaml:

 

resources:
- name: destination
  parameters:
    service-plan: lite
    service-name: AppTestWeb_destination
    service: destination
  type: org.cloudfoundry.managed-service
- name: AppTestWeb_html_repo_runtime
  type: org.cloudfoundry.managed-service
  parameters:
    service: html5-apps-repo
    service-plan: app-runtime
- name: AppTestWeb_html_repo_host
  type: org.cloudfoundry.managed-service
  parameters:
    service: html5-apps-repo
    service-plan: app-host
- name: uaa_AppTestWeb
  type: org.cloudfoundry.managed-service
  parameters:
    path: ./xs-security.json
    service: xsuaa
    service-name: AppTestWeb-xsuaa-service
    service-plan: application
and my client http to test the destination:
$http({
            method: 'GET',
            url: "/confiar",
        }).success(function (response, status, headers, config) {
            alert("esponse"+ response);
            alert(status);
        }).error(function (response, status, headers, config) {
             alert("Err "+response + status);
        });
My destination is config with name: confiar. portocol: HTTP , Proxy: Internet . is a simple REST Srvice.
Can you help me?, i dont know why i'm getting a 404 not found. If yo need my code appreciate your great help.
Thanks again

 

 

 

 

 

mariusobert
Developer Advocate
Developer Advocate
Hi Alfredo,

 

the first thing that I noticed when I look at your xs-app.json is that the order of the routes seems off. The first route matches everything and basically "catches" all traffic which means no traffic is sent to the second route. Try to reverse them and maybe it works then.
jalf1991
Explorer
0 Kudos
Hi mariusobert

 

I tried it but still getting the same 404 not found...

 

The test:

{

    "welcomeFile": "/index.html",

    "authenticationMethod": "route",

    "logout": {

        "logoutEndpoint": "/do/logout"

    },

    "routes": [



        {

            "source": "^/confiar/(.*)$",

            "target": "/$1",

            "destination": "confiar"

        },

         {

            "source": "^(.*)$",

            "target": "$1",

            "service": "html5-apps-repo-rt",

            "authenticationType": "xsuaa"

        }


    ]

}



Other thing  that you can see


Thanks


mariusobert
Developer Advocate
Developer Advocate
0 Kudos
Which URL do you request? Please be aware that you need to match the regex fully.

A request to "/confiar" won't match because it's missing the closing / and something "behind it".
jalf1991
Explorer
0 Kudos

Hi mariusobert

case from CF (app deployed):

the URL is  : The URL Path is: "https://xxxxxcfecctrial-dev-apptestweb-approuter.cfapps.eu10.hana.ondemand.com/nsHTML5Module/index.html"

When i deploy in CF the app and run it get 404 not found in the destination's request.

 

mariusobert i show you another interest data:

 

My destination has the attributes:

destination attribute

package.json

{
  "name": "apptestweb",
  "version": "0.0.1",
  "devDependencies": {
    "@sap/ui5-builder-webide-extension": "1.0.x",
    "@ui5/cli": "2.2.6",
    "eslint": "5.16.x",
    "@sap/eslint-plugin-ui5-jsdocs": "2.0.x",
    "@sapui5/ts-types": "1.71.x",
    "bestzip": "2.1.4",
    "rimraf": "3.0.2",
    "@sap/approuter": "9.3.0",
    "@sap/html5-repo-mock": "2.0.0"
  },
  "ui5": {
    "dependencies": [
      "@sap/ui5-builder-webide-extension"
    ]
  }
}
mta.yaml
    commands:
    - npm run build
    supported-platforms: []
resources:
- name: destination
  parameters:
    service-plan: lite
    service-name: AppTestWeb_destination
    service: destination
  type: org.cloudfoundry.managed-service
- name: AppTestWeb_html_repo_runtime
  type: org.cloudfoundry.managed-service
  parameters:
    service: html5-apps-repo
    service-plan: app-runtime
- name: AppTestWeb_html_repo_host
  type: org.cloudfoundry.managed-service
  parameters:
    service: html5-apps-repo
    service-plan: app-host
- name: uaa_AppTestWeb
  type: org.cloudfoundry.managed-service
  parameters:
    path: ./xs-security.json
    service: xsuaa
    service-name: AppTestWeb-xsuaa-service
    service-plan: application
build-parameters:
  before-all:
  - builder: custom
    commands:
    - npm install
ui5.yaml
specVersion: '1.0'
metadata:
  name: HTML5Module
type: application
resources:
  configuration:
    propertiesFileSourceEncoding: UTF-8
builder:
  resources:
    excludes:
      - "/test/**"
      - "/localService/**"
  customTasks:
  - name: webide-extension-task-updateManifestJson
    afterTask: generateVersionInfo
    configuration:
      appFolder: webapp
      destDir: dist
  - name: webide-extension-task-resources
    afterTask: webide-extension-task-updateManifestJson
    configuration:
      nameSpace: ns
  - name: webide-extension-task-copyFile
    afterTask: webide-extension-task-resources
    configuration:
      srcFile: "/xs-app.json"
      destFile: "/xs-app.json"
manifest.json
{
    "_version": "1.12.0",
    "sap.app": {
        "id": "ns.HTML5Module",
        "type": "application",
        "i18n": "i18n/i18n.properties",
        "applicationVersion": {
            "version": "1.0.0"
        },
        "title": "{{appTitle}}",
        "description": "{{appDescription}}",
        "resources": "resources.json",
        "ach": "ach",
        "sourceTemplate": {
            "id": "html5moduletemplates.basicSAPUI5ApplicationProjectModule",
            "version": "1.40.12"
        },
        "crossNavigation": {
            "inbounds": {
                "intent1": {
                    "signature": {
                        "parameters": {},
                        "additionalParameters": "allowed"
                    },
                    "semanticObject": "Dynamic",
                    "action": "display",
                    "title": "{{appTitle}}",
                    "info": "{{appTitle}}",
                    "subTitle": "{{appSubTitle}}",
                    "icon": "sap-icon://sales-order"
                }
            }
        }
    },"sap.cloud": {
        "service": "com.sap.jalf.app"
    },
    "sap.ui": {
        "technology": "UI5",
        "icons": {
            "icon": "",
            "favIcon": "",
            "phone": "",
            "phone@2": "",
            "tablet": "",
            "tablet@2": ""
        },
        "deviceTypes": {
            "desktop": true,
            "tablet": true,
            "phone": true
        }
    },
    "sap.ui5": {
        "flexEnabled": false,
        "rootView": {
            "viewName": "ns.HTML5Module.view.TestView",
            "type": "XML",
            "async": true,
            "id": "TestView"
        },
        "dependencies": {
            "minUI5Version": "1.60.1",
            "libs": {
                "sap.ui.core": {},
                "sap.m": {},
                "sap.ui.layout": {}
            }
        },
        "contentDensities": {
            "compact": true,
            "cozy": true
        },
        "models": {
            "i18n": {
                "type": "sap.ui.model.resource.ResourceModel",
                "settings": {
                    "bundleName": "ns.HTML5Module.i18n.i18n"
                }
            }
        },
        "resources": {
            "css": [
                {
                    "uri": "css/style.css"
                }
            ]
        },
        "routing": {
            "config": {
                "routerClass": "sap.m.routing.Router",
                "viewType": "XML",
                "async": true,
                "viewPath": "ns.HTML5Module.view",
                "controlAggregation": "pages",
                "controlId": "app",
                "clearControlAggregation": false
            },
            "routes": [
                {
                    "name": "RouteTestView",
                    "pattern": "RouteTestView",
                    "target": [
                        "TargetTestView"
                    ]
                }
            ],
            "targets": {
                "TargetTestView": {
                    "viewType": "XML",
                    "transition": "slide",
                    "clearControlAggregation": false,
                    "viewId": "TestView",
                    "viewName": "TestView"
                }
            }
        }
    }
}
Thanks for you help. 
  
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
I just added a video that explains how to make sure your destination is working. Maybe it helps you.
mariusobert
Developer Advocate
Developer Advocate
I meant which URL is expected to return the data from the destination. If you set everything up correctly, it should be similar to:

https://xxxxxcfecctrial-dev-apptestweb-approuter.cfapps.eu10.hana.ondemand.com/confiar/.

If that doesn't work, it could mean that your destination is not working as expected. Here's a brand-new video tutorial that explains how you can test it.
jalf1991
Explorer
0 Kudos

Yes, my endpoint is like that:

https://xxxxxcfecctrial-dev-apptestweb-approuter.cfapps.eu10.hana.ondemand.com/confiar/.

 

I am testing the destination and i am getting the next result:

DestinationTestCurl

 

My destination endpoint (origin endpoint)is not passing by SAP Cloud Connector, is not a problem, really? or it is necessary to do it,  i need to pass my endpoint (Is a internet endpoint) exposing in my SCC? i guess for this case is not necessary but i don't really know...

CheckConnectionDestination

TestConnectionDestinationCF

 

The connection it's OK . Endpoint Basic Auth it's Ok too!.

 

What could be?. My endpoint is a API REST App Java deployed in SAP NEO.  Simple internet endpoint...

Thanks for the video! and

Thanks for your help

mariusobert
Developer Advocate
Developer Advocate
Try it without the "WebIDEUsage" and the "HTML5Preset" properties. Use just these two:

jalf1991
Explorer
Thanks so much, you are the best man!

 

I already got an answer, it is only necessary to place those two properties!!

 

Again, thanks so much for your help and appreciate your time a lot!

 
jalf1991
Explorer

Hi Again  mariusobert

I got a result OK making the Curl test destination. It's OK.

I made a test running my app html5 from BAS IDE and the result is OK Too, The destination is consumed from the app without problem.  Response OK

My app running from BAS and service xsuaa and destination (bindign from BAS)

AppRunningFromBassIDE

 

Now i am deploying my app html5 to CF with own service instance (created from mta.yaml). When  the app is deployed, is making binding with the services:

ServicesIntanceCFapp

Finally when i run my app, the app get response 404 NOT FOUND when the destinations is consume...

 

why the app works in BAS  but when I deply show this 404 not found. ? I need to do smothing more? 

 

***UPDATE**: 11/03/2021

mariusobert  I got the solution!. 

 

 

JérémyChabert
Participant
0 Kudos
Hello mariusobert ,

I have open a question that might be related to this.

Could you have a look ?

https://answers.sap.com/questions/13318318/request-proxied-differently-thought-called-from-th.html
WRoeckelein
Active Participant
0 Kudos

Hi alfredosemeco ,

***UPDATE**: 11/03/2021

mariusobert  I got the solution!. 

And what is the solution exactly?

Thanks,

  Wolfgang

WRoeckelein
Active Participant
0 Kudos

Hi mariusobert ,

Try it without the "WebIDEUsage" and the "HTML5Preset" properties.

so WebIDEUsage is not needed for BAS?

Regards,

Wolfgang

mariusobert
Developer Advocate
Developer Advocate
0 Kudos
I can't give you an official answer here but I don't think it's needed. At least not in any of the scenarios that I use regularly 🙂
WRoeckelein
Active Participant
0 Kudos
Hi mariusobert ,

thank you very much for the fast answer!

Of course another question would be if this entry would be harmful...

IMHO we need a definitive list of properties necessary for BAS.

Regards,

Wolfgang
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
I agree - a definitive guide would be nice but hard to implement as each service can add their own additional props as needed.

For the SAP Business Application Studio, I found an official answer in the documentation 🙂

Here, they also mention that just WebIDEEnabled is required (I guess you problem is just caused by WebIDEUsage as it assumes you connect to ABAP ABAP system).

 

And there's another document describing the additional props related to HTML5 apps.
WRoeckelein
Active Participant
0 Kudos
Hi mariusobert ,

yes, I agree a single guide would be too hard. But a least a guide per use case (and not only per tool) would be nice.

Based on the docu and the screenshot I would guess Alfredo did not have "HTML5Preset" but "HTML5.PreserveHostHeader".

So both "WebIDEUsage" and "HTML5.PreserveHostHeader" are among those are strictly and optionally needed for a BAS-based deployment of HTML5 app to CF and therefore should definitly not give any problems.

Regards,

Wolfgang
0 Kudos
Hi Marius Obert,

I'm treating to Migrate an application from NEO environment to Cloud Foundry environment and I want to consume a destinations I followed the stepts you showed us. I created the destination in Cloud Froundry


also I set up mta.yml file


then I set up xs-app.json file


now I treating to call the distination like you did in the toturial


but when I test the application the browser show me the following


I don't know what I'm doing wrong I will waiting for your answer and thanks for help me
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
Hi,

The things that I see in your screenshots looks right so I would assume that the problem is not related to your code but actually to your destination. I tried to open the URL from your first screenshot with my browser and I also get a 404 response.

So please make sure the app is running and the destination is set up correctly. Then, please follow the instructions from the linked video above to test your destination.

 

 
0 Kudos
Hi Marius,

Yeah. you were right the destination was wrong, but when I fix it:


then I test the application again but I still get the issue:


the app is running link_api  is weird I don't know what't going on
mariusobert
Developer Advocate
Developer Advocate
0 Kudos
Now that the destination is fixed, did you create a new project? Maybe the old project is still using the invalid destination configuration.