Closed phangkw closed 4 years ago
Hi @phangkw,
I think Batch is not a part of the type-safe client, but a separate function you have to import. @FrankEssenberger, am I correct. Can we update our docs to reflect this necessity?
Hello phangkw,
the batch requests are done differently the the normal OData request. Here is a detailed tutorial on how to use batch:
https://developers.sap.com/tutorials/cloudsdk-js-odata-batch-changeset.html
However, with the SuccessFactor API we had always some problems in the past, because upsert
is a very common method there, but it is not an official OData or RESTfull keyword. There you only have the four CRUD as you mentioned. So currently we do not generate these methods for entities. Sometimes they are modeled as function imports
in the edmx, then you can find them as function imports.
Perhaps you can share the edmx file (frank.essenberger@sap.com) and tell me which methods you want to invoke. Then I can have a look and see if they are generated or if it is possible that we add support for that.
If you can not find it in the function imports
and we realize that a support of these methods is not possible easily I would suggest you use the untyped client:
https://github.com/SAP/cloud-sdk/blob/master/packages/core/src/http-client/http-client.ts
with the method: executeHttpRequest
. With this you also get all the destination lookup, auth features of the SDK but can execute plain HTTP request.
Best Frank
e had always some problems in the past, because
upsert
is a very common method there, but it is not an official OData or RESTfull keyword. There you only have the four CRUD as you mentioned. So currently we do not generate these methods for entities. Sometimes they are modeled asfunction imports
in the edmx, then you can find them as function imports. Hi Frank,
This is the EDMX file which we are using. This is only 1 out of many entity we are trying to do so that we can perform an upsert / batch functions.
or u can find it under the attachment. ECEmploymentInformation (3).zip
When we try to call the batch / chargeset, it is not available.
If you can not find it in the function imports and we realize that a support of these methods is not possible easily I would suggest you use the untyped client:
https://github.com/SAP/cloud-sdk/blob/master/packages/core/src/http-client/http-client.ts
with the method: executeHttpRequest. With this you also get all the destination lookup, auth features of the SDK but can execute plain HTTP request.
Hi Frank, will you be able to provide one sample snippet code on how can we make use of the call to executeHttpRequest, so sorry that i'm not able to figure out how can we implement this to retrieve the response.
============================================================================== This was the sample snippet code i have extracted from api hub.
var data = null;
var xhr = new XMLHttpRequest(); xhr.withCredentials = false;
xhr.addEventListener("readystatechange", function () { if (this.readyState === this.DONE) { console.log(this.responseText); } });
//setting request method //API endpoint for API sandbox xhr.open("GET", "https://sandbox.api.sap.com/successfactors/odata/v2/EmpJobRelationships");
//API endpoint with optional query parameters //xhr.open("GET", "https://sandbox.api.sap.com/successfactors/odata/v2/EmpJobRelationships?$top=integer&$skip=integer"); //To view the complete list of query parameters, see its API definition.
//Available API Endpoints //https://api2.successfactors.eu/odata/v2 //https://apisalesdemo2.successfactors.eu/odata/v2 //https://api2preview.sapsf.eu/odata/v2 //https://api4.successfactors.com/odata/v2 //https://apisalesdemo4.successfactors.com/odata/v2 //https://api4preview.sapsf.com/odata/v2 //https://api5.successfactors.eu/odata/v2 //https://api8.successfactors.com/odata/v2 //https://apisalesdemo8.successfactors.com/odata/v2 //https://api8preview.sapsf.com/odata/v2 //https://api10.successfactors.com/odata/v2 //https://api10preview.sapsf.com/odata/v2 //https://api012.successfactors.eu/odata/v2 //https://apirot.successfactors.eu/odata/v2 //https://api12preview.sapsf.eu/odata/v2 //https://api15.sapsf.cn/odata/v2 //https://api16.sapsf.eu/odata/v2 //https://api17preview.sapsf.com/odata/v2 //https://api17.sapsf.com/odata/v2 //https://api18preview.sapsf.com/odata/v2 //https://api18.sapsf.com/odata/v2
//adding request headers
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Accept", "application/json");
//API Key for API Sandbox
xhr.setRequestHeader("APIKey", "
//Available Security Schemes for productive API Endpoints //Basic Authentication
//Basic Auth : provide username:password in Base64 encoded in Authorization header
//xhr.setRequestHeader("Authorization", "Basic
//sending request xhr.send(data);
=========================================================================
Hello phangkw ,
I will have a look at the edmx file as soon I find some time. Regarding the http client you would call it like this:
const destination = {
destinationName: <yourDestinationName>,
jwt: <yourJwtToken>
}//You can also give the destination object directly here. But the lookup is more convinient.
const config = {
method: HttpMethod.GET,
params: {
a: 'a',
b: 'b'
}
};
const response = await executeHttpRequest(destination, config);
Best Frank
Hello phangkw ,
I will have a look at the edmx file as soon I find some time. Regarding the http client you would call it like this:
const destination = { destinationName: <yourDestinationName>, jwt: <yourJwtToken> }//You can also give the destination object directly here. But the lookup is more convinient. const config = { method: HttpMethod.GET, params: { a: 'a', b: 'b' } }; const response = await executeHttpRequest(destination, config);
Best Frank
=================================================================================
Hi Frank, thank you very much. Managed to perform the API call as per the explanation.
Just added my codes as below just incase others people encountering the same issues as I struggle in the past 2 weeks. =).
<the code might not be the best but it works !>
================================================================================= //Adding the libraries from the sap cloud sdk/core. const { retrieveJwt, executeHttpRequest, HttpMethod } = require("@sap-cloud-sdk/core");
exports.
const destination = {
destinationName:
//Used Promise instead of await / sync. it just work vice versa. return new Promise((resolve, reject)=>{
executeHttpRequest(destination, config)
//axios.get('https://api.github.com/users/mapbox')
.then((response) => {
resolve(response.data);
});
});
} }
Good that we have a working solution for the moment. We will also add some code example and information in our docu page: https://sap.github.io/cloud-sdk/.
In order to close the issue I also looked at the client generated by the VDM. As I expected the upsert
is not represented and support would be tricky. So in this case use the work around I mentioned. For batch I see in the BatchRequest.ts
or typescript analogon. With this you can do batch request as described in the tutorial mentioned above with something like:
const updateRequests = businessPartnerAddresses.map(address => BusinessPartnerAddress.requestBuilder().update(address));
const [updateChangesetResponse] = await batch(changeset(...updateRequests)).execute({
url: 'https://my.s4hana.ondemand.com/'
});
Best Frank
Hi Expert,
What I have done is to download the OData definition (EDMX file) from API Hub and generated the functions via the npx generate-odata-client --inputDir service-specs --outputDir generated --forceOverwrite command. The system is generated correctly.
We are currently able to follow most of the tutorial from https://sap.github.io/cloud-sdk/docs/js/features/odata/overview for both "C" - Post, "R" - Get, "U" - Put and "D" - Delete accordingly. But when we tried to follow the example given in the blog for Batch Requests# ( retrieve requests and changesets ) , we are not able to follow as the batch and changeset function is not defined in our generated class. Can you kindly advice is there anywhere which we can do "UPSERT" or "BATCH" function using SDK ? and if you can provide some example, it will be great help.
Example of batch and changeset for businessPartnerAddress (sample) but this is not generated as part of the npx generate command.
updateAddresses(businessPartnerAddresses: BusinessPartnerAddress[]) :Promise<BusinessPartnerAddress[]> { const updateRequests = businessPartnerAddresses.map( address => BusinessPartnerAddress .requestBuilder() .update(address) );
const [updateChangesetResponse] = await batch(changeset(...updateRequests)) .execute(destination);
return (updateChangesetResponse as WriteResponses) .responses .map( response => response.as(BusinessPartnerAddress) ); }