How to consume an OData Service with JQuery?
In general all requests can be done with the $.ajax function.
$.ajax can specify all HTTP Methods, send data to any URL wanted and realize success and error callbacks. $.get and $.post could be convenient.
In principle, you specify the HTTP method in the type attribute.
$.ajax({
url: "https://YOUR_SYSTEM/sap/byd/odata/cust/v1/your_service/Collection..",
type: 'GET', /* or POST or DELETE or PUT or PATCH or MERGE */
datatype: 'json',
data: { amount: '12.34' },
success: function(oResult) { /* do something */ }
error: function(oResult) { /* do something */ }
});
However, only GET and POST are perfectly supported. Other methods might be not supported by the server or client or are blocked by some firewall.
For best compatibility, create POST requests and set the header x-http-method to the wanted method with the headers attribute
$.ajax({
url: "https://YOUR_SYSTEM/sap/byd/odata/cust/v1/your_service/Collection..",
type: 'POST',
headers: { 'x-http-method': 'MERGE' /* or PUT or PATCH or DELETE */ },
datatype: 'json',
data: { amount: '12.34' },
success: function(oResult) { /* do something */ }
error: function(oResult) { /* do something */ }
});
Create
To create an instance,, you execute a post request to the collection of the topmost node and pass the data. The callback is called with the created node.
The data can describe one node only (e.g. Root) or a complete hierarchy of nodes (e.g. Root with some Items and with some Parties,…). The callback is called with the topmost node.
$.post(
"https://YOUR_SYSTEM/sap/byd/odata/cust/v1/your_service/YourCollection",
oData,
function(oResult) { /* do something */ }
);
As described in How to “Consume an OData Service with OpenUI5 / SAPUI5?”, you can read the created hierarchy in the callback. Execute a Retrieve to the provided node and expand to the children you are interested in.
Retrieve
To retrieve data, execute a GET request.
You can request multiple entries
$.get("https://.../your_service/YourCollection...",
function(oResult) { /* do something */ }
);
or just one
$.get("https://.../your_service/YourCollection('...')",
function(oResult) { /* do something */ }
);
Update
The payload needs to include the keys. This is usually ObjectID and for children often ParentObjectID.
OData supports to update methods. PUT and MERGE.
PUT replaces the node data, sets the stated properties as given and reverts all others to there default values.
$.ajax({
url: "https://.../your_service/YourCollection('...')",
type: 'POST',
headers: { 'x-http-method': 'PUT' },
datatype: 'json',
data: { ObjectID: '0123...CDEF', amount: '12.34' },
success: function() { /* do something */ },
error: function(oError) { /* do something */ }
});
MERGE updates only the stated properties with the new values.
$.ajax({
url: "https://.../your_service/YourCollection('...')",
type: 'POST',
headers: { 'x-http-method': 'MERGE' /* or PATCH */ },
datatype: 'json',
data: { ObjectID: '0123...CDEF', amount: '12.34' },
success: function() { /* do something */ },
error: function(oError) { /* do something */ }
});
Delete
To delete an instance, execute a delete request directly to this instance.
$.ajax({
url: "https://.../your_service/YourCollection('...')",
type: 'POST',
headers: { 'x-http-method': 'DELETE' },
success: function() { /* do something */ }
error: function(oError) { /* do something */ }
});
Function Imports
During the modeling of the Function Imports in SAP Business ByDesign OData Services Modeller, you configured the request method.
- For queries, it is always GET.
- For action, it is usually POST (does not really matter and is supported without overwrite), but could also be PUT or DELETE.
To use the Function Import execute a request to the Functio Import URL with the correct method.
$.ajax({
url: "https://.../your_service/your_function_import",
type: 'GET', /* or DELETE or POST or PUT */
datatype: 'json',
data: { amount: '12.34' },
success: function(oResult) { /* do something */ }
error: function(oError) { /* do something */ }
});
Security
Data write access is protected by a CSRF token. This can be fetched with a header X-CSRF-Token: Fetch and needs then be added as a header X-CSRF-Token: <thetoken> with the requests. There is no harm in providing the token with all requests.
$.ajaxSetup({
beforeSend: function(oXhr) {
oXhr.setRequestHeader("X-CSRF-Token", sTheToken);
}
});
Hi Thomas,
I need to call a Function Import using 'POST'. This function import contains a property of type Edm.String which I need to supply as well.
My call is as follows:
However, when this call is executed, the breakpoint in the Function import on the backend is never hit. i.e. the function import is never called.
In the network tab of Chrome developer tools the request looks as follows:
I also do not see any errors in the /IWFND/ERROR_LOG on the gateway.
Do you know what could be the issue ?
Regards,
Melwyn
Hi Melwyn,
I think, you need to provide the parameters via GET (even if the request itself is POST), so please try something like
or
Thanks and regards,
Thomas.
Hi Thomas,
just tried to load some data from a gateway service. The serice worls fine when called from browser directly, but via jquery, I get 401 error (not authenticated).
The codes is the following:
Any idea?
Many thanks!
ben
Hi Ben.
Did you login to ByDesign first?
if not, please see
https://blogs.sap.com/2017/03/13/how-to-login-to-an-sap-business-bydesign-system-with-javascript/
for an example how to do it in JavaScript.
Thanks and regards,
Thomas.
Hi Ben.
Another thing could be, but I would assume another kind of error code, if you try to do a cross-domain access from JavaScript.
For testing in localhost or something best start your browser without security protection.
Another really nice thing is to use SAP Cloud Platform and access System via a destination. Here, your application is only talking to the server it was started on and this one handles the authentication/tunneling transparently.
(Description: https://blogs.sap.com/2017/03/13/how-to-access-an-sap-business-bydesign-system-via-sap-cloud-platform/)
Thanks and regards,
Thomas.