Skip to Content
Technical Articles
Author's profile photo Archana Shukla

Calling External API In Custom Task UI of Workflow in Cloud Foundry

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

 

Assigned Tags

      14 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Vladimír Balko
      Vladimír Balko

      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.

      Author's profile photo Archana Shukla
      Archana Shukla
      Blog Post Author

      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

      Author's profile photo Vladimír Balko
      Vladimír Balko

      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.

      Author's profile photo Jimmy Arnold Moreno Nuñez
      Jimmy Arnold Moreno Nuñez

      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.

      Author's profile photo Archana Shukla
      Archana Shukla
      Blog Post Author

      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/

       

      Author's profile photo Jimmy Arnold Moreno Nuñez
      Jimmy Arnold Moreno Nuñez

      Thank you so much Archana.

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

      Author's profile photo József Huszkó
      József Huszkó

      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

      Author's profile photo Archana Shukla
      Archana Shukla
      Blog Post Author

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

      Author's profile photo József Huszkó
      József Huszkó

      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.
      Author's profile photo Archana Shukla
      Archana Shukla
      Blog Post Author

      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

      Author's profile photo József Huszkó
      József Huszkó

      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!

      Author's profile photo Koray Yersel
      Koray Yersel

      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

      Author's profile photo Koray Yersel
      Koray Yersel

      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

      Author's profile photo Huseyin Yalcin
      Huseyin Yalcin

      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.gttft1Service

      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.