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: 
Archana
Product and Topic Expert
Product and Topic Expert
In this last blog of the series I would help you understand how you can access APIs (cloud or on-premise) from workflow task UI.

In the current scenario, all the companies have hybrid environment with SAP, non-SAP, cloud and on-premise systems and solutions. With the new wave of process orchestration, automation and digitization, companies require integration of SAP, non-SAP systems. There are different interfaces (SOAP, RFC, BAPI, IDOC, REST, OData etc.) that are available to establish communication between SAP and non-SAP systems to exchange data.

In SAP Cloud Platform Workflow, the integration channel with other cloud services or SAP S/4HANA or LoB applications is via APIs. Service task is the BPMN task type to call APIs in Workflow and SAP Cloud Platform Connectivity service is the medium to establish the connection between these systems. If the external service is OData or Rest based, then it can be directly consumed from Workflow using destination. For any other interface, cloud integration service is recommended to be used. (learn more about the service task)

 


 

External APIs can also be called from user task UI and it could be little tricky to call these APIs as it is not as simple as filling the configuration properties of the service task.  I would now explain you step-by-step how it can be achieved.

Prerequisite:

  • You have already created an MTA project with workflow module

  • You have already created and designed Fiori Module and configured your workflow user task to this module.

  • You have already created a FLP Module with app-router configurations to access workflow applications


 

Step 1: Create destination


Destination is to be created at sub-account level for connecting to different systems. These systems can be accessed via internet or on-premise. There could be different protocols to access the APIs like Basic Authorization, OAuth, Client Certificate etc. The destination has to be appropriately created based on the supported authentication protocol.

 

Below as the samples for these different destinations. I have picked 3 examples,

  • first one is the northwind with No Authentication,



 

  • then is SuccessFactors destination with Basic Authorization



 

  • Finally, on-premise S/4HANA destination with Basic Authorization.
    Note: For on-premise system there need to be a cloud connector setup.



 

Step 2: Update xs-app.json of Fiori Application


 

  • Create a destination route in xs-app.json


{
"source": "^/NorthWind_Dest/(.*)$",
"target": "/$1",
"destination": "northwind",
"authenticationType": "none"
}

 

Similarly create any other routes for other destinations.

         


 

Step 3: Update mta.yaml of MTA project


As you are trying to access the destination from CF application, you therefore need to add the dependency of destination service and/or connectivity service instance to the app-router from where you are accessing the My Inbox application.

Note: If you are accessing internet based destination then you need only destination service instance dependency. If you are using on-premise based destination then you also have to use connectivity service instance together with destination service.

For this first add the service instance details in the resources section


 

Then add the dependency of the destination and/or connectivity service instance in the app-router.


 

Caution: if you miss this step then the Component.js of your user task UI wont load and you will get 500 – Internal Server Error as the app-router will try and look for the destination.

cdm.js:66 2020-09-07 23:55:46.422770 Cannot create componentsap.demo.bpm.taskui for smart template rendering. Showing standard task in the detail screen as a fallback: failed to load 'sap/demo/bpm/taskui/Component.js' from /sapdemobpmtaskui/Component.js: 500 - Internal Server Error

 

Step 4:  Code Fiori Application to call External API


In the final step, you now have to code your Fiori application to call the needed service. In this example I have coded jQuery.ajax method to call Http URL endpoint for Northwind.


 

Note the URL. It has application ID followed by the route name and then the relative URL
/<applicationID>/<route-name>/<relative-URL>

For Example: I wanted to call this URL in my custom task UI: https://services.odata.org/V3/Northwind/Northwind.svc/Suppliers?$format=json

  • This would be broken up as follows:

    • The destination northwind (in cockpit), will have the url as https://services.odata.org

    • Routes in xs-app.json of the Fiori application will have a route of name Northwind_Dest pointing to above northwind destination created in the cockpit

    • In the AJAX call, the URL will be formed as "/sapdemobpmtaskui/Northwind_Dest/V3/Northwind/Northwind.svc/Suppliers?$format=json

      • where sapdemobpmtaskui is theapplication ID and Northwind_Dest is the source name of the destination route given in xs-app.json

      • Use manifest.json to sap.app --> id to get the application ID






 

<<<<< NEW >>>>>>

If you are using SAP Managed app-router based application then your prefix will be as follows.
/<app-modulepath>/<route-name>/<relative-URL>
For Example: /workflow-sample.sapdemobpmtaskui-1.0.0/Northwind_dest/Northwind.svc/Suppliers

You can use this code to get the module path:

var appId = this.getOwnerComponent().getManifestEntry("/sap.app/id");

var appPath = appId.replaceAll(".", "/");

var appModulePath = jQuery.sap.getModulePath(appPath);

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>




  • In my example, I adjusted the view.xml as well to bind the data from the service call to the UI5 control



 

After you build and deploy the MTA, open the task in the My Inbox and click on the country drop down, you will see the countries getting loaded. (ignore the duplicate country names).



This is how you code your workflow custom task UI application to work with any external API call for any GET, POST, PATCH etc. methods. The same will be applicable with SFSF or any Lob Application APIs or any backend on-premise APIs.

  • For easy learning purpose, I have uploaded the code used in this blog as example in GitHub.

    • Download the content from resources folder, import into SBAS, build and deploy.




 

Related Resources

 
16 Comments
vbalko-claimate
Active Participant
0 Kudos
Great blog series Archana!

I would also like to see in such blog the information about how to get csrf token for POST calls - especially for on premise calls.
Archana
Product and Topic Expert
Product and Topic Expert
Hello Vladimir,

This blog is about calling external API from custom task UI and not from workflow service task. To answer you question:

  • XSRF token is needed in 2 instances (a) when you are calling any API from the application which is routed via app-router and (b) when you making an on-premise API call

  • For on-premise API call if there are no specific XSRF token URL then you can use the same API URL as for POST, GET etc. see the image below


vbalko-claimate
Active Participant
0 Kudos
My fault - I didnt realized that I`m speaking about service task and you about UI task.

I just searched info about that topic recently, so it came to my mind.

 

Btw - thank you for the answer anyway.
former_member664593
Participant
0 Kudos
Hi Archana.

It's necessary create a destination in cloud foundry if I want to call bpmworkflowruntime? Because when I execute my function to start my workflow I get the error 404.

Thanks in advance.
0 Kudos
Hi there!

 

I followed all the instructions in this post, but I always get an error when running the application:

"Route references unknown destination "

I am trying to call a CPI (Integrator) endpoint which gets data from an SAP system.

Could you help me out please?

 

Thanks in advance!

Have a great day,

Jozsef
Archana
Product and Topic Expert
Product and Topic Expert
0 Kudos
No, bpmworkflowruuntime does not need a destination. You may want to refer another blog of mine which explains how to start the workflow from custom application

https://blogs.sap.com/2020/08/27/starting-workflow-from-custom-fiori-application-in-cloud-foundry/

 
Archana
Product and Topic Expert
Product and Topic Expert
0 Kudos

It's difficult to suggest anything with this limited information. Can you post the route & destination snapshot that you are creating.

former_member664593
Participant
0 Kudos

Thank you so much Archana.

My error was my ID app in URL, I ignored the capital words and finally is working =).

0 Kudos
We created the destination in the Cloud Platform (in a subaccount), and then we are trying to call that destination in our sap business application studio. This destination have a few properties: WebideEnabled - true, Html5.dynamicDestination - true.

Our xs-app.json:


{

  "authenticationMethod": "none",

  "routes": [

    {

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

     "target": "cpi_CLONING",

     "destination": "cpi_CLONING",

     "authenticationType": "none"

    }

]

}

And the mta.yaml is the same as yours.


Although we have 2 xs-app.json, one is "global", the other one is inside the approuter folder.

When we write the approuter's xs, we get no error but nothing happens. When we use the "global" xs-app.json, we get an error: Router references unknown destination.


We have no clue what to do.


Archana
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Jozsef,

The explanation is simple. Your UI5 application is routed via app-router. There will be two xs-app.json (a) one inside the UI5 application and (b) one in app-router. If you are using destination inside your UI5 application, then (a) you have add the route inside the xs-app.json of your application and (b) the authentication method has to be "route" and not "none" (as in your case).

 

Regards,

Archana
We solved it, the problem was that we had to include the namespace ("ns") when calling a destination.

So for example, insted of GET("/dest"), we had to write GET("/ns/dest").

 

Have a great day!
korayyersel_q
Participant
0 Kudos
Hi Archana,

eventhough I have added the connectivity dependency, the route for the cc destination in xs-app.json causes the problem that you have described:

Cannot create componentcom.qperior.workflowsample.uifor smart template rendering. Showing standard task in the detail screen as a fallback: failed to load 'com/qperior/workflowsample/ui/Component.js' from /comqperiorworkflowsampleui/Component.js: 500 - Internal Server Error -

What can be the cause? The destination works fine in a different MTA project with portal and ui modules. Can I see the 500 error with more detail somewhere? I have tried to run cf logs on approuter and ui-deployer it didn't brought anything up.

Thanks and Regards,

Koray
korayyersel_q
Participant
0 Kudos
Hi Archana,

I could solve my problem. The thing is I have two approuters, actually two MTAs. One for standard workflow tiles (inbox, definitions, manage instances) and one for the specific application. For task UIs I had to bind conn/dest to the approuter, which belonged to the workflow tiles project. Thanks again for the CF workflow blogs.

Regards,

Koray
0 Kudos

Hi Archana,

 

I try to consume this Odata service which is running on the cloud multi-environement as API as you see below.

https://xxxxxxxxxx.cfapps.eu10.hana.ondemand.com/api/outbound/odata/v1/com.emea.gtt.app.gttft1.gttft...

I can call this service on the browser with technical user and password. Also I developed an application in NEO environment by defining destination , and it is also running there without any problem.

But when i try to call this service Cloud Foundry by defining the destination with basic auth method, I always receive 401 error. Even if I deploy the application in the same Multi-Enviroment.

I guess, my configuration is also correct if you check it below.

 

Where am I doing wrong? Is it possible having a restriction on this cloud service? If yes, why I am not allowed to use it in the same environment?

 

Thanks in advance.

verreydthans
Participant
0 Kudos
Hi,

Still facing some issues here. We're working with the SAP Managerd AppRouter

Steps that we did:

- Create Destination in cockpit

- xs-app.json
{
"source": "^/S4HANA_Development_Dest/(.*)$",
"target": "/$1",
"destination": "S4HANA_Development",
"authenticationType": "none"
},

- mta.yaml
added in resources:
- name: default_connectivity
type: org.cloudfoundry.existing-service
parameters:
service: connectivity
service-plan: lite
- name: default_destination
type: org.cloudfoundry.existing-service
parameters:
service: destination
service-plan: lite

But need to include this also in a module? Which one?
We have following modules:
modules:
- name: xxx-destination-content
- name: xxx-app-content
- name: xxx-uimodule

in my Manifest, I added our service:
is this correct, or do we need to use the Ajax call for this in controller or component??

"dataSources": {
"mainService": {
"uri": "/sap/opu/odata/sap/ZAPI_SRV/",
"type": "OData",
"settings": {
"annotations": [],
"localUri": "localService/metadata.xml",
"odataVersion": "2.0"
}
}
}

We see that the call to our service is now:
https://xxx.sap-process-automation.cfapps.eu10.hana.ondemand.com/xxx.xxxuimodule-0.0.3/sap/opu/odata...
Or with the Destination name:
https://xxx.sap-process-automation.cfapps.eu10.hana.ondemand.com/xxx.xxxuimodule-0.0.3/S4HANA_Develo...

Buit both URL's gives a "Internal Server Error"

 

Thanks in advance!
verreydthans
Participant
0 Kudos
archana.shukla , I don't have the FLP module, is it required to use Destinations from the cockpit?