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: 
ale_biagi
Product and Topic Expert
Product and Topic Expert
NOTE: this blog post is intended for developers who have previous experience in developing CAP applications which consume either OData or REST APIs using SAP Business Application Studio and SAP BTP destinations, as well as handling communication scenarios and communication arrangements in S/4HANA Cloud.

Introduction


You may have realized that most modern cloud applications are built to interact with other external solutions via OData and/or REST APIs (and you may have already done it yourself in several opportunities). But, there are some solutions that still do not offer 100% of services as OData or REST, providing some interfaces via SOAP web services - this is the case, for example, of S/4HANA Cloud which exposes a variety of OData services but, for same cases, still sticks with SOAP web services.

If you started programming in the last 5 years, you might not even know what I'm talking about - or if you know, it's the fault of some legacy system you have to deal with.

SOAP, or Simple Object Access Protocol (not to be confused with SOA), is a protocol for creating distributed and decentralized web services - the famous web services - which allow the exchange of information between systems, using the XML format. I don't know when this started, but the latest version is from 2007 (1.2) and was the most popular way of connecting systems in the first decade of the 2000s, before the emergence of the REST protocol that encouraged web APIs with JSON and, later, microservices - lighter ways to exchange information between systems over the web.

As previously mentioned almost all the latest web and mobile technologies offer native (or close to) support for handling REST Web APIs, but little is said about SOAP connections. The purpose of this blog post is precisely to help those who need to deal with NodeJS CAP applications on the client and SOAP on the server.

Application Architecture


We are going to build a simple CAP application that reads Business Users from S/4HANA Cloud (which are exposed exclusively via a SOAP web service).

You can view the application architecture bellow:


Figure 1 - Application Architecture



Preparation Steps


Before we move forward with the instructions, let's first get prepared for development by completing the following two basic steps:

  1. Set up a destination to your S/4HANA Cloud system using a communication user (not a business user). You can name your destination S4HC just to be compatible with the further instructions in the post. If you have trouble creating your destination just follow this tutorial on SAP Developers.

  2. Jumpstart a new CAP project in SAP Business Application Studio: after opening your dev space, open a new terminal window, move to the "projects" directory and initialize a new blank project with cds init business-users. Open the newly created project in a workspace to get ready for development.


Download Web Service Definition


The first thing we need to do is to get the web service definition which is described in WSDL (Web Services Description Language).

WSDL is an XML notation for describing a web service. A WSDL definition tells a client how to compose a web service request and describes the interface that is provided by the web service provider.

We can get such definition from SAP API Business Hub, so access https://api.sap.com.

In the home page, first make sure to login to API Business Hub (NOTE: you must login for the download process to work properly), then, after login, click on the S/4HANA Cloud tile.


Figure 2 - Login to SAP API Business Hub and access S/4HANA Cloud section


In the next page, click on the APIs tab, then, in the find box, type "business user read" and press enter. Finally, click on the Business User - Read tile.


Figure 3 - Locate Business User - Read SOAP API


In the next page, click on API Specification.

NOTE: make sure your communication user (set up in your destination) has access to communication scenario SAP_COM_0193 or SAP_COM_0093, via some communication arrangement, as indicated below:


Figure 4 - Access API Specification


Click on the down arrow next to WSDL and save the QUERYBUSINESSUSERIN.wsdl file in your local computer.


Figure 5 - Download QUERYBUSINESSUSERIN.wsdl


Now, go to your CAP project in Business Application Studio and create a folder named "external" under the "srv" folder, then drag & drop the recently downloaded QUERYBUSINESSUSERIN.wsdl file into it like demonstrated below:


Figure 6 - QUERYBUSINESSUSERIN.wsdl file imported to CAP project


This definition will be used later upon creation of the web service client..

Create Reference to Web Service Host


The next step is to reference the web service in the project's package,json file. So, open it up and insert the following code snippet right before the last curly bracket:
,
"cds": {
"requires": {
"UserRead": {
"kind": "SOAP",
"credentials": {
"destination": "S4HC",
"path": "/sap/bc/srt/scs_ext/sap/querybusinessuserin"
}
}
}
}

After the insertion, your package.json file should look like the screenshot below:


Figure 7 - Reference to web service in package,json


Notice that the reference is pointing to the destination that has been previously created in BTP with the path to the actual service location.

Although the destination already points to the S/HANA Cloud host, as the WSDL file has been downloaded from SAP API Business Hub (not directly from a communication arrangement in the actual S4/HANA Cloud tenant), the service location within it is "generic", meaning it's just a "placeholder" in the format of "https://host:port/<service path>".

Therefore, we still need to replace such placeholder with the actual S/4HANA Cloud tenant host. So, open-up the WSDL file and search for "location" (it's usually at the end of the file) and replace all occurrences of "host:port" with your S/4HANA Cloud tenant host (set up in your destination), like demonstrated below:

UPDATE NOTE (May 9th, 2022): the code snippets in this blog post have been updated to dynamically set the service endpoint at runtime (thank you @Mukteshwari Rathore for the valuable insights on the setEndpoint method from the soap node package explained in your comments!). So, you can skip this step if you wish.


Figure 8 - Replace host:port with actual tenant host


Now, the project is fully set up to communicate with the web service via the application code.

Bind Destination and XSUAA Services


Before moving on to binding the services to your project, make sure to login to Cloud Foundry either via the BAS command palette (View > Find Command) or command line interface (CLI) in the terminal.

After login, create the destination and XSUAA service instances using the command lines below:

  • cf create-service destination lite busers-dest

  • cf create-service xsuaa application busers-xsuaa


Upon successful creation of the service instances, on the left-hand pane of BAS click on the Cloud Foundry icon (small light bulb), then on the refresh button at the top right of the pane.

The newly created instances should be displayed at end of the list, like demonstrated below:


Figure 9 - Newly created service instances


Right click on the busers-dest service instance and select "Bind service to a locally run project" and, then, in the dialog, make sure the business-users folder is selected and click on the "Select folder for .env file" button.


Figure 10 - Select business-users folder


Now, repeat the same procedure for the busers-xsuaa service instance.

Click again on the Explorer icon in the left-hand pane and, then, in the refresh button at the right of the project name. You should see the .env file that has been created like demonstrated below:


Figure 11 - .env file for services binding


Now, we need to rename that file to default-env.json and transform its contents into JSON format (as it's just defining a regular environment variable called VCAP_SERVICES which is not in the expected JSON format), like demonstrated below:


Figure 12 - Rename .env and adjust to JSON format



Install Dependencies


To facilitate the creation of SOAP clients and avoid to much effort preparing a SOAP envelope in XML format to invoke the web service's methods via HTTP request, we can use a pre-built NodeJS SOAP client manager from the "soap" package available on npm (in Java there's already native support for SOAP web services).

Also, to create an asynchronous http client and easily fetch destination data from BTP, we will utilize the  "http-client" and "connectivity" node packages from the SAP Cloud SDK respectively.

So, let's install those dependencies by running the following commands:

  • npm install soap

  • npm install @Sap-cloud-sdk/http-client

  • npm install @Sap-cloud-sdk/connectivity


NOTE: if you intend to deploy your application to Cloud Foundry later, you must also install the "passport" package, as the latest CDS version is enforcing security on bootstrap when deployed to production.

And, finally, to install the other dependencies from the original jump-started package.json we just run:

  • npm install


And with that, we are now fully ready to start the development!

Create Module to Handle SOAP Clients


In a productive scenario, we usually would have more than one web service being manipulated throughout the application code, so it's convenient to create a module with a function that facilitates the creation and handling of SOAP clients and can be largely reused.

Under the "srv" folder create a folder named "lib" and, in that folder, create a file named "soap-service.js" like demonstrated below:


Figure 13 - Create soap-service.js file


Open-up that file and paste the following code snippet into it:
const soap = require('soap');
const client = require('@sap-cloud-sdk/http-client');
const connectivity = require('@sap-cloud-sdk/connectivity');

// Helper to create a soap service through the BTP destination service
async function getSoapService(service, wsdl, endpoint) {
// Get the service reference
var definition = cds.env.requires[service];
// Get the destination data from BTP
const dest = await connectivity.getDestination({ destinationName: definition.credentials.destination });
// Get service endpoint
const url = (dest.url.substr(dest.url.length-1,1) === '/') ? dest.url.substr(0,dest.url.length-1) : dest.url;
endpoint.url = url + definition.credentials.path;

// Create an httpClient which connects over the BTP destination
var httpClient = {
request: async function (url, data, callback, exheaders, exoptions) {
client.executeHttpRequest(dest, {
method: 'POST',
url: url,
data: data,
headers: exheaders
}, {...exoptions, fetchCsrfToken: false}).then((result) => {
callback(null, result, result.data);
}).catch((e) => {
callback(e);
});
}
}

// Instantiate the service using that http client
return soap.createClientAsync(wsdl, { httpClient: httpClient });
}

module.exports = {
getSoapService
}

The code is quite simple: the getSoapService function receives the service name (defined in package.json) and the wsdl file location with the service description, then fetches the destination data from BTP and uses it to get the service endpoint and create an HTTP client, which is then passed to the createClientAsync function from the soap package, that returns a promise to get the actual SOAP client later in the application code.

Create Handler to Read Business Users


Now, we must create a handler function which will invoke the web service method that returns the business users from S/4HANA Cloud as response.

In the "lib" folder, create a file named "handlers.js" like demonstrated below:


Figure 14 - Create handlers.js file


Open-up that file and paste the following code snippet into it:
const { getSoapService } = require('./soap-service');

let userReadServicePromise = null;
let userReadServiceEndpoint = { url: null };

(async function () {
// Connect to external S/4HC SOAP service
userReadServicePromise = getSoapService('UserRead', './srv/external/QUERYBUSINESSUSERIN.wsdl', userReadServiceEndpoint);
})();

/*** HANDLERS ***/

async function readBusinessUser(req) {
try {
// Get the SOAP client for the UserRead service
const userReadService = await userReadServicePromise;
userReadService.setEndpoint(userReadServiceEndpoint.url);

// Set the parameters for the QueryBusinessUserIn method of the sevice
const param = {
BusinessUser: {
PersonIDInterval: {
IntervalBoundaryTypeCode: 9,
LowerBoundaryPersonID: "0000000000"
},
BusinessPartnerRoleCodeInterval: {
IntervalBoundaryTypeCode: 9,
LowerBoundaryBusinessPartnerRoleCode: "000000"
}
},
QueryProcessingConditions: {
QueryHitsUnlimitedIndicator: true
}
};

// Invoke QueryBusinessUserIn method asynchronously and wait for the response
const resp = await userReadService.QueryBusinessUserInAsync(param);

// Prepare the actual service response
const busUsers = [];
if (resp && resp[0] && resp[0].BusinessUser) {
resp[0].BusinessUser.forEach(busUser => {
busUsers.push({
ID: ((busUser.User) ? busUser.User.UserID : busUser.PersonID),
FirstName: busUser.PersonalInformation.FirstName,
LastName: busUser.PersonalInformation.LastName,
PersonFullName: busUser.PersonalInformation.PersonFullName,
BusinessPartnerRoleCode: busUser.BusinessPartnerRoleCode,
HasUser: ((busUser.User) ? true : false)
});
});
}

return busUsers;
} catch (err) {
req.error(err.code, err.message);
}
}

module.exports = {
readBusinessUser
}

Upon module loading, a promise to the service is created by the getSoapService function, which is, then, used in the readBusinessUser handler to get the actual SOAP client for the UserRead service referenced in package.json. The QueryBusinessUserIn method of the service is invoked asynchronously, passing a few required parameters (basically filters and query processing definitions), and the response is finally formatted into the expected CAP service response.

Create the CAP Service Definition


Now that we have the complete business logic of the application we can create the CAP service definition to expose the data fetched from S4/HANA Cloud via a service entity and attach the handler function to its READ event.

In the "srv" folder, create a file named "busers-service.cds" like demonstrated below:


Figure 15 - Create busers-service.cds file


Open-up that file and paste the following code snippet into it:
namespace sap.extensions.soap.busers;

service BusinessUsers @(path : '/bussiness-users') {
entity BusinessUser {
ID : String(12);
FirstName : String(128);
LastName : String(128);
PersonFullName : String(258);
BusinessPartnerRoleCode : String(6);
HasUser : Boolean;
}
}

Here we are just exposing a non-persistent entity named BusinessUser containing only some relevant fields to be fetched from S/4HANA Cloud.

Attach the Handler Function to the READ Event


The last step is to attach the handler function to the READ event of the BusinessUser entity, so the CAP service can be called to retrieve the business users data from S/4HANA Cloud and return it to the client as an OData v4 response.

In the "srv" folder, create a file named "busers-service.js" like demonstrated below:


Figure 16 - Create busers-service.js file


Open-up that file and paste the following code snippet into it:
const cds = require('@sap/cds');
const {
readBusinessUser
} = require('./lib/handlers');

module.exports = cds.service.impl(async function () {
/*** SERVICE ENTITIES ***/
const {
BusinessUser
} = this.entities;

/*** HANDLERS REGISTRATION ***/
// ON events
this.on('READ', BusinessUser, readBusinessUser);
});

As you can see, the readBusinessUser handler is attached to the ON READ event of the BusinessUser entity.

Test the Application


Finally, we are all set! So, let's test the application by running cds watch and, then, CTRL+Click on the http://localhost:4004 link to open-up the CAP service home page in a new tab:


Figure 17 - CAP service home page


Now, click on the BusinessUser entity link and, after some seconds, you should get the JSON containing the Business Users from your S/4HANA Cloud tenant, like demonstrated below:


Figure 18 - Business users from S/4HANA Cloud tenant


And that's it! A fully working CAP service consuming a SOAP web service from S/4HANA Cloud.

Conclusion


After completing the steps from this blog post you should have successfully developed a CAP service which communicates with S/4HANA Cloud via SOAP web service to fetch its business users.

Notice that this web service is specifically for reading data, and you could use such information in your application's logic for some specific action or even to expose it to a UI via the built-in OData v4 framework from CAP.

In the second case, you could either manually implement the logic to support the OData operations such as $select, $count, $filter, $search etc. - by interpreting the SELECT query provided by CAP's CQL (CDS Query Language) via the request object - or completely hand it over to the CAP framework - by importing the business users to an entity in a data model and exposing it in the service as a projection.

If you want to execute other operations on business users' data you can use another web service which is the ManageBusinessUser (the counterpart of QueryBusinessUser).

To learn more on how to use such services, please refer to SAP's official documentation using the links below:

Hope you enjoyed this post and that it may be useful in your future developments.

Please, do not hesitate to submit your questions in SAP Community through the Q&A tag link: https://answers.sap.com/index.html

 

 
29 Comments
MustafaBensan
Active Contributor
0 Kudos

Hi alessandro.biagi,

This is a much-needed NodeJS example of consuming S/4HANA Cloud SOAP APIs as OData via the SAP Cloud SDK.  Thanks for sharing.  I have a couple of questions:

1.  What considerations should be taken into account to extend this approach to SOAP APIs that support create, update and delete operations?

2.  The previously recommended approach for consuming SOAP APIs using the SAP Cloud SDK is based on Java, as described in the post Deep Dive 18 with SAP Cloud SDK: Convenient Consumption of SAP S/4HANA SOAP APIs.  Which of the two approaches is recommended now, NodeJS or Java?

Regards,

Mustafa.

ale_biagi
Product and Topic Expert
Product and Topic Expert

Hi mbensan,

Thanks for reaching out.

Please, see comments below:

1. Assuming that you are developing with CAP, if you want to "translate" all SOAP calls into OData you would need to consume the CRUD operations from the APIs in the corresponding CREATE, READ, UPDATE and DELETE events of the associated entities. By doing so, you'll be basically creating a "conversion middleware" between the original API and the client. Now, if the purpose is just to consume the APIs in some parts of your application's business logic (i.e. update the role of a specific user under certain conditions), then you just call the appropriate method whenever your logic requires.

2. Pleaso, note that this post focus on consuming the APIs from a CAP application with the SAP Cloud SDK being used only to read destination data and not to do the actual SOAP call, whilst the post you mention focus exclusively on SAP Cloud SDK to perform the API calls (it's not a CAP application), which are totally different approaches. The SAP Cloud SDK has no support for direct SOAP calls in NodeJS, thus the usage of a soap npm package is still required either way. So, the decision on what technology/approach to use depends on the requirements and constraints of your specific project/use case. There's no preconceived recipe that points to a "one size fits all" approach.

Hope I have answered your questions accordingly.

Regards,

Alessandro

MustafaBensan
Active Contributor
0 Kudos
Hi alessandro.biagi,

Thanks for your quick and detailed response.  This has given me some good options to consider for my use cases.

Regards,

Mustafa.
ale_biagi
Product and Topic Expert
Product and Topic Expert
Hi mbensan,

You're welcome!

Regards,

Alessandro
MustafaBensan
Active Contributor
0 Kudos
Hi alessandro.biagi

I have another question after looking into this approach further.  In the case of a CAP multi-tenant SaaS application that needs to consume S/4HANA Cloud SOAP APIs from the subscribed Consumer Subaccount, is there a way to dynamically update the S/4HANA Cloud tenant host in the WSDL file instead of doing this manually?

Regards,

Mustafa.
ale_biagi
Product and Topic Expert
Product and Topic Expert

Hi mbensan,

First let me just do a short clarification: the manual replacement explained in the post is only required because the WSDL has been downloaded from SAP API Business Hub. You can also download it directly from S/4HANA Cloud via some communication arrangement using one of the communication scenarios indicated in the post. When you do it, the tenant host is already present in the WSDL.

Now, in terms of having it dynamically set upon SaaS subscription, actually the most efficient way to handle WSDL is to point directly to the service endpoint at the host appending the "?WSDL" parameter. You can do it by getting the host and path from the destination, BUT, unfortunately, it does not work in S/4HANA: you always need to download it from the tenant (at least I couldn't find any other way).

As the soap package that manages the clients expects a URL (which can be local a file) for the WSDL, there's no way to interfere in the XML deserialization as it is done internally in the package, so you could replace the host.

With that being said, maybe a workaround for this scenario would be to store the original WSDL from SAP API Business Hub in a separate folder as a fixed "template" and, then, in the on subscription event, create a copy of it in a folder with the same name of the SaaS tenant that is being created, do the replacement in that copy and start using it from then on.

For that work some prerequisites should be met, like having the destination properly created before doing the subscription a well as enforcing it to have a specific predefined name so it can be read upon SaaS subscription.

Hope it helps to answer your question.

Regards,

Alessandro

MustafaBensan
Active Contributor
0 Kudos
Thanks alessandro.biagi.  You have once again provided some helpful options to investigate.

Regards,

Mustafa.
ale_biagi
Product and Topic Expert
Product and Topic Expert
0 Kudos
You're welcome mbensan!

Regards,

Alessandro
thomas_jung
Developer Advocate
Developer Advocate
A SOAP service consumed and re-exposed as OData. What dark magic is this? 😉 Excellent and incredibly useful!
ale_biagi
Product and Topic Expert
Product and Topic Expert
0 Kudos
Thanks thomas.jung!
Hi mbensan

I think ideally we shouldn't be passing  the host and port in WSDL, as customers host and port could be anything based on their S/4 HANA Cloud system instead it's a good way to take from destination url

 

Below worked for me

I am calling the SOAP service for S/4 HANA Cloud in my nodeJs based CAP application,

I used below function from node soap library which allows me to pass the destination url to soap to directly connect to S/4 HANA Cloud system


  this.soapClient = await soap.createClientAsync(wsdl);

                    this.soapClient.setSecurity(

                        new soap.BasicAuthSecurity(

                            this.dest.originalProperties.User,

                            this.dest.originalProperties.Password

                        )

                    );

this.soapClient.setEndpoint(this.dest.url);





And the call to the corresponding CRU functions like below




await this.soapClient.ContractAccountCreateAsync(

                args

            );




Where args would be the JSON request data ( yes node SOAP does accept JSON input and return beautiful JSON output 🙂 No handling of complex xml required





Also for connecting to S/4 HANA Cloud , I didn't prepare httpclient via CloudSDK,executehttprequest, node soap automatically handled it. However for on Premise system , you might need little tweak in order to handle the calls via cloud connector
yevgen_trukhin
Advisor
Advisor
0 Kudos
Yes, unfortunately, there are still many use cases where SOAP only is available. Good blog!
yevgen_trukhin
Advisor
Advisor

Concur to what Mukte mentioned regarding host/port. You dont need to modify host/port in WSDL.

MustafaBensan
Active Contributor
0 Kudos
Hi mukteshwari.rathore,

Thanks for providing this dynamic determination approach.  Very helpful.

Regards,

Mustafa.
former_member730860
Discoverer
0 Kudos
Hi alessandro.biagi,

Great article. Thanks for sharing the info.

I have a few questions:

  1. Does CAP Java also support the consumption of SOAP services?

  2. If so, would CAP take care of multitenancy like it normally does or should we handle it explicitly?


Regards,

Viswa
ale_biagi
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi viswanathvankadara,

  1. To consume SOAP services in Java you just need to use a Java SOAP client from some framework (i.e. Spring) instead of the NodeJS SOAP client described in the post.
  2. The multitenancy handling feature of CAP has no relation to services consumption (either REST, OData, openAPI, SOAP etc.). In that sense you just need to care about the appropriate destination(s) configuration in the consumer subaccount. The rest is taken care by your application logic.

Hope this answers your questions.

Regards,

Alessandro

former_member730860
Discoverer
0 Kudos
Hi alessandro.biagi,

Thanks for the response. Pardon me I'm pretty much new to SOAP.

I didn't frame my second question correctly. My bad. I wanted to ask how one can map the S/4 HANA Cloud system and that customer's corresponding BTP tenant. You answered that question in one of the previous comments.

The thing is my use case is slightly different where I'm not firing a SOAP request rather I'm trying to receive SOAP messages pushed by an S/4 service. I'm trying to find a correlation between my use case and the contents mentioned in the blog.

Any suggestions/ideas are welcome.

Regards,

Viswa
ale_biagi
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hi viswanathvankadara,

The goal of the application described in this post is to directly call a SOAP web service from an external solution (SAP or non-SAP), meaning the flow is from the application to the external solution and not the other way around (having the external solution - i.e. S/4HANA - to push messages that are consumed by other applications).

The scenario you described is called decoupled communication and can be achieved by using the SAP Event Mesh service on BTP: https://help.sap.com/docs/SAP_EM

In that scenario your application will consume messages that are pushed by the external solution (i.e. S/4HANA) to a message queue.

CAP can natively "listen" to such message queues to automatically pull messages from there and hand over to your application for further processing: https://cap.cloud.sap/docs/guides/messaging/

Regards,

Alessandro
ale_biagi
Product and Topic Expert
Product and Topic Expert
0 Kudos
Thank you mukteshwari.rathore for the valuable insights on the setEndpoint method of the SOAP client from the soap node package!

I updated the snippets in the post accordingly, so it's not required to modify the downloaded WSDL any longer (although I still explain that the placeholder is in there).

Best Regards,

Alessandro
former_member730860
Discoverer
0 Kudos
Hi alessandro.biagi

Our requirements would not be completely fulfilled by the events on S/4 but there is a SOAP service in S/4 HANA Cloud that matches our requirements. That is why we're going ahead with SOAP-based communication.

Regards,

Viswa
madhav15
Explorer
0 Kudos

Hi alessandro.biagi,

Thanks for sharing a great blog. I am trying to send SOAP POST request in CAP using public API from Business Accelerator Hub. Can you suggest me approach for POST request.

This is my API : /sap/bc/srt/scs_ext/sap/journalentrycreaterequestconfi

Regards,

Madhav

ale_biagi
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi madhav.machiwal,

SOAP webservices follow the OO paradigm, hence they work in a similar way as regular objects in an OO programs (leveraging "methods" to read and write data to the object). So, they kind of "mask" GET and POST requests into those "methods".

You must got through the desired service documentation to understand which method(s) perform POST(s) request(s) and implement it following the the service specs.

But keep in mind that some SOAP webservices only support GET requests (like the one from this blog) or even only POST requests. This is why it's important to read and understand the corresponding documentation.

This blog invokes a method that reads data (GET request). In the same way, it could invoke another method  that writes data (POST request), if it was available in the service.

Regards,

Alessandro

madhav15
Explorer
0 Kudos
Hi alessandro.biagi

Thanks for explaining the concept. I have checked out required documentation of SOAP API which I am using. Actually I am new with concept of SOAP and CAP and I am not able to achieve POST request. Can you suggest me any blog or documentation.
ale_biagi
Product and Topic Expert
Product and Topic Expert
0 Kudos
SOAP: https://www.guru99.com/soap-simple-object-access-protocol.html

CAP: https://cap.cloud.sap/docs/

Please, see the disclaimer (note) at the very beginning of this blog post.
prem_selvam
Discoverer
0 Kudos

Hello alessandro.biagi
We are trying to achieve the Business User read using On-Premise SOAP API and built the custom handler as you mentioned in the blog, but we could not read the Business user available in the system. we are getting 404 error while calling the operation :  QueryBusinessUserInAsync

 resp = await userReadService.QueryBusinessUserInAsync(param);

 

after executing this line it is returning: AxiosError: Request failed with status code 404

API: https://api.sap.com/api/OP_QUERYBUSINESSUSERIN/overview

Can you help us achieve the same for an On-Premise SOAP API?

prem_selvam
Discoverer
0 Kudos
Hello alessandro.biagi

We are working on a scenario on creating a Down Payment Document in On-Premise S4 system from CAP Application. As I couldn't find any OData service for creating a Down Payment Document we are trying to achieve it via SOAP API. We are trying to connect to On-Premise SOAP API through the Destination maintained in Cloud Connector for the on-Premise system.
I followed above custom handler to reach the destination SOAP API and post with a payload parameter to create the document but we are facing difficulties to achieve the same using a custom handler. Can you guide on achieving a post call to a On-Premise SOAP API from a CAPM application. Your insights to achieve this will really help us.
ale_biagi
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi prem_selvam,

There's no way of calling a SOAP webservice in CAP other than via the implementation of a custom handler.

The difference from your scenario to the one detailed in the blog is that you're writing data to the backend system instead of reading.

Therefore, what you need to do is to handle the 'CREATE' event of your entity instead of 'READ'. Then, in the handler you should invoke the appropriate method from the SOAP webservice with the documented payload to create the desired object in the backend system.

Regards,

Alessandro

 

 

pavuluri_anoop
Explorer
0 Kudos
Hello,

I have been able to do a POST call to a soap API in S/4 On premise by following this approach and tweaking it a little bit.

https://api.sap.com/api/OP_JOURNALENTRYBULKLEDGERCREATIONREQ_IN/overview

I am able to create the required entries using the API and also see the success messages in the AIF monitor. However, I am struggling to understand how to call the outbound service to read the confirmation of posting as per this document. There are only configuration and payload related instructions, but nothing about how to call this outbound endpoint in code. (https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/3ab6e6fc510f4840a5508e126ef01e22/fc4632e12e464cf480d...)

Could anyone please advice how to achieve this?

alessandro.biagi
kcezar
Explorer
0 Kudos

Hi @ale_biagi 

I am implementing your solution for communicating with a non-SAP SOAP service. This service is authenticated via PFX certificate. So I made a series of settings that I will explain below. The request is made, I have already made a series of modifications and tests including the xml generated by the soap library within the SoapUi application.

Add Certitifcation PFX

soap-service.jssoap-service.js

However, I'm having a very peculiar situation, running in BAS, it's giving me an error:

Erro By AxiosErro By Axios

In the response data we have the following excerpt:
AddressFilterMismatch.png

The funniest thing is that I take content sent by request and send it through the SoapUi app. It works perfectly and gives me the expected business treatment.

SoapUi.png

As I developed the solution inspired by your knowledge @ale_biagi , I believe you can help me But anyone who wants to participate is welcome, I haven't seen any blog with an explicit implementation of the soap service call with a pfx certificate.

I would like to invite  @Jacky_Liu  to this question, as his article below served as a knowledge base for me as well.

https://community.sap.com/t5/technology-blogs-by-sap/deploy-a-rest-api-application-on-btp-cloud-foun...

I've been trying to make this happen for two months and I used the following sources below to study:

Soap SSL PFX Certification Security:
https://www.npmjs.com/package/soap#clientsslsecuritypfx

Consuming Services
https://cap.cloud.sap/docs/guides/using-services

SAP Cloud SDK Http Client
https://sap.github.io/cloud-sdk/api/v3/modules/sap_cloud_sdk_http_client.html

Axios wdsl options:
https://axios-http.com/docs/req_config

I would greatly appreciate the help or advice from any member of the community, thank you in advance.