Skip to Content
Technical Articles

Best practices for web service calls

Hi, I’m Alexis Gaillot from SAP and I’m working on the SAP Intelligent RPA product in the adoption team.

In this blogpost I will show you how to work with web services using the ajax.call function of SAP Intelligent RPA 1.0 and how to investigate if your call does not work as expected.

 

This blogpost will be cut in different parts

  • Context
  • Reasons
  • Causes and Resolutions
    • Client Certificates
    • Server Certificates
    • Cookies
    • Tokens
  • Examples of Best Practices
    • Postman
    • cURL
    • Terminal commands
    • Ajax Call
  • Conclusion

 

Context

When you use the ajax.call function to communicate with a web service, you receive a status from the server such as:

  • 200.
  • 300.
  • And so on.

Sometimes, it seems that the call does not work and you receive a generic error message. This can be:

  • The status only.
  • A generic message.

It can be difficult to know where the issue comes from.

 

Reasons

Web services can combine many different settings:

  • Certificates on server/client side.
  • SSL Certificates, which encrypt information, provide authentication and so on. They are necessary if you want to authenticate on the server.
  • Tokens.

 

Causes and Resolutions

In this part, you can find the main causes of issues and how to resolve them.

In the following topics, you will learn more about:

  • Client certificates
  • Server certificates
  • Cookies
  • Tokens

 

Client Certificates

You use Client certificates to authenticate on a server. Sometimes you cannot connect to a server with a certificate.

You can use the option ignoreClientCertificate to avoid the certificate authentication.

ctx.ajax.call({ 
	url: url, 
	method: 'GET', 
	contentType: "application/json", 
	headers: headers, 
	ignoreClientCertificate: true, 
	success: function(res, status, xhr) { 
		rootData.xCSRF = xhr.headers["x-csrf-token"]; 
			
		var value = xhr.headers["Set-Cookie"]; 
	    rootData.Cookies = value.split('; ')[0] + "; "; 
			
		sc.endStep(); 
	}, 
	error: function(xhr, status, statusText) { 
		ctx.log('error get') 
		sc.endStep(); 
	} 
}); 

 

Server Certificates

API may need such certificates. They are generally mandatory.

ctx.ajax.call is not able to force the call without those certificates.

Moreover, you cannot specify which certificates to use as you are not in a browser environment.

In this case you will need to use cURL, for more information see the chapter Examples of Best Practices below.

 

Cookies

Cookies allow you to authenticate client requests and keep all session information.

If you need to use cookies in your calls, you must set a cookie to keep this information. You will then be able to use it in another call.

Example:
ctx.ajax.call({ //First call, get the cookies information 
	url: "[url]", 
	method: e.ajax.method.get,			
	contentType: e.ajax.content.json, 
	usePassport: true, 
	ignoreClientCertificate:true, 
				
	headers : { 
		'Authorization': 'Basic [base 64 login:password]', 
		'X-CSRF-Token': 'Fetch' 
	}, 

	success: function(res, status, xhr) { 		
	        try { 	
			var csrf = xhr.headers['x-csrf-token']; 
			var cookie = xhr.headers['Set-Cookie']; 
			var myUrl = "https://domainName/sap/opu/odata/sap/xxx"; 
				
			ctx.ajax.call({ //Second call, use the cookies in the headers object 
			         url: myUrl,  
			         method: e.ajax.method.post, 	
			         ignoreClientCertificate:true, 
			         contentType: 'application/json;charset=utf-8', 
			         headers : { 
			                 'Content-type': 'application/json;charset=utf-8', 
			                 'X-CSRF-TOKEN': csrf, 
			                 'Cookie': cookie 
		                }, 
		                success: function(res, status, xhr) { 
				          ctx.log("Good call");
		                }, 
		                error: function(xhr,res,status) { 
                                    ctx.log("Something went wrong with the call");
		                } 
	                }); 			
              } catch (ex) { 	
                     ctx.log("Something went wrong : " + ex.description);		
              }  
        },
}); 

 

Tokens

A token is a piece of data created by a server that contains information to identify a user and the token validity. If you use the token incorrectly in the Ajax call, it may lead to an issue. Like the cookies, the token needs two calls.

For instance, you make an API call in the Factory. You use the first call to get the token. The second call triggers the API call and it creates a job in the job queue. In this case, the calls are linked. The second call happens if the first one is successful.

Example:
ctx.ajax.call({ //First call, get the token 
	url: serviceAccount.urls.accessTokenURL, //Url got from the service key “url parameter +  /oauth/token?grant_type=client_credentials” 
	method: e.ajax.method.get, 
	contentType: e.ajax.content.json, 
	header:{ 
		Accept: e.ajax.content.json, 
		Authorization: 'Basic ' + ctx.base64.encode(serviceAccount.credentials.clientID + ':' + serviceAccount.credentials.clientSecret, false) // clientID and clientSecret got from the service key 
	}, 
	success: function(res, status, xhr) { 
		ctx.log('Token generated'); 
		sc.localData.Token = 'Bearer ' + ctx.get(res, 'access_token'); 
		ctx.ajax.call({ // Second call 
			url: serviceAccount.urls.apiTriggerURL, //Url from the API trigger (end with “/run”) 
			method: e.ajax.method.post, 
			contentType: e.ajax.content.json, 
			header:{ 
			    Accept: e.ajax.content.json, 
			    'irpa-api-key': serviceAccount.urls.irpaTriggerToken, //Token get from the API trigger 
			    Authorization: sc.localData.Token 
			}, 
			data:{  
			    //Payload of your API Trigger 
			}, 

			success: function(res, status, xhr) { 
			   ctx.log('success'); 
			   sc.endStep(); 
			   return; 
			}, 
		    error: function(xhr, status, statusText) { 
			   //web service failed 
			   sc.setError(e.error.Fail, 'Web service failed: [' + status + ']' + statusText + ' - ' + xhr.responseText); 
			   sc.endScenario(); 
		           return; 
			} 
		}); 
	}, 
	error: function(xhr, status, statusText) { 
		//web service failed 
		sc.setError(e.error.Fail, 'Web service failed: [' + status + ']' + statusText + ' - ' + xhr.responseText); 
		sc.endScenario(); 
		return; 
	} 
}); 

 

Examples of the Best Practices

Here are some examples of the best practices for Web Service Calls.

As stated before, due to the complexity of the Ajax call, you may face different issues.

To assess these issues with the Ajax call, you can use multiple tools:

  • Postman
  • cURL
  • Terminal commands
  • Ajax Call

Let see first what are they exactly and what we can do with them.

 

Postman

Postman is a tool that allows you to interrogate and test Web services and API calls.

This tool has multiple features and is easy to use.

 

cURL

cURL is a command-line tool that you can use to get or send data including files using URL syntax.

On Windows 10 build 17063, cURL is included by default.

 

Terminal Commands

In the Command Prompt, you can test the cURL command during the assessment.

If the test is successful, the agent calls the cURL command through the terminal.

 

Ajax Call

 

How to configure your Ajax call function

If you do not know how to configure the Ajax call function, follow this process:

  1. Make the request work on Postman

Note : If it does not work even with Postman, it means that you cannot make it work with the Ajax call function.

 

a. When it works, click the Code button.

b. Choose the programming language you work with (should be “JavaScript – jQuery“)

Note: You can see different languages in the red box on the left. Here, we choose the JavaScript-jQuery language because the Ajax call function has been developed with the jQuery.ajax() method. In the green box, you notice the code generated by Postman.

2. Use this code in the Ajax call function

Copy and paste this code in the Desktop Studio and adjust the code if necessary. For more information, see the official documentation on the call function

function getCall(success, error, localData){

	var result;
	var url = localData.fetchAPI = "";
						
	//API call to get csrf token and cookies
	ctx.ajax.call({
		method: e.ajax.method.get,
		url: url,
		contentType: e.ajax.content.json,
		headers: {
			'Authorization': localData.auth,
			'x-csrf-token' : 'fetch',
			'Cookie' : 'fetch',
			'Accept' : 'application/json'
		},
		ignoreClientCertificate: localData.clientCert,
		success: function(res, status, xhr) {
						
			if(res.d){
			result = xhr;
			success(result);
			} else {
				result = res;
				error(result);
			}
		
		},
		error: function(xhr, error, statusText) {
						
			result = res;
			error(result);
						
		}
	});

 

How to deal with Ajax call issues

If you still face issues during the call (issues from the xhr object) after you performed the test in the previous process, try the following tests:

  1. Try ctx.ajax.call with the option ignoreClientCertificate as true
Note : If it still does not work, check the error code, that can lead you to the origin of the error.
       2. Change the settings in Postman

By default, the SSL certificate verification is not enabled in Postman. This means that it forces the call even if the certificate is not available.

If the call on Postman does not work after you enabled this option, this means that this certificate is mandatory to make the call. As stated before, the Ajax call does not have this option.

One solution could be to use cURL.

 

3. Try the cURL code given by Postman

  • Follow the How to configurate my Ajax call function process above, from step 1.a. to step 1.b., to retrieve the proper cURL code.

  • In this code, remove all characters \ and replace all the simple quotation marks with double quotation marks.
  • Run the cURL code on Command Prompt.

 

Example:

curl --location --request GET "http://XXXX"

If you have an error message that appears with the cURL code, do a search on the Internet. The error messages are usually very explicit. If the code is successful, you can integrate it in an SAP Intelligent RPA call.

 

  • Implement this code in the Desktop Studio
var cmdCurl = 'curl -k --location --request GET "http://XXXX" 
ctx.exec(cmdCurl, 60, function(reqres) { 
	var reqdata = ctx.json.parse(reqres.output); 
});

Note : The option -k is used to ignore the client certificates.

 

 

Conclusion

You know now how to use the web service calls and how to investigate when you encounter an issue.

With SAP Intelligent RPA 2.0 it will be easier. Stay Tune.

To know more, you will find further information on the official documentation following this link

2 Comments
You must be Logged on to comment or reply to a post.