Skip to Content

SAP Cloud Platform, API Management offers many out of the box API Security best practices which can be customized based on your enterprise requirements.  These API Security Best Practices includes security policies for Authentication and Authorization,  Traffic Management and many more.

Rate limiting or Traffic Management is the process of controlling the rate of traffic sent or received by an API endpoint. Rate limiting can have many flavors like limiting the call based on no of hits to the APIs in a given time range, limit the calls for sudden spike in given time range, limit the calls for too many concurrent connections, limiting the calls for high amount of data. Rate Limiting API call blog covers the various flavors of API rate limit supported by SAP Cloud Platform API Management.

In this blog we will cover the API rate limiting for OData ( an OASIS standard that defines a set of best practices for building and consuming RESTful APIs) batch calls. OData batch calls allows a client to pass multiple HTTP request batched inside a single HTTP request to the OData server. Therefore for API Rate limiting, individual requests inside the batch request should be considered for the calculation of the applicable quota. Using a combination of JavaScript policy and MessageWeight property of the Quota Policy from SAP Cloud Platform API Management  such dynamic API rate limiting can be easily achieved.

Prerequisites

Launch API Portal

 

  • Click on the link Access API Portal to open API Portal.

 

Rate limiting for OData batch calls

In this section we would describe the usage of the JavaScript policy to calculate the number individual requests inside a single Batch call to set the message weight property of the Quota policy dynamically.

Refer Rate limit API calls blog to create an API Proxy to an OData API from SAP Gateway and applying an API Rate limit using Quota policy. In this blog we would be extending the same to add the support for OData batch calls
  • Navigate to the Define from the hamburger icon, then select the tab APIs. Select the API Proxy to which API Rate limiting was applied.

 

  • Click on the Policies button of  the selected API Proxy.

 

  • Click on the Edit button from the Policy designer and then from Scripts tab click on the + button to add the JavaScript file for calculating number of requests in the batch call.

  • In the Create Script dialog provide the name of the JavaScript file say maincode and then select Create from the Script drop down. Finally click on the Add button.

 

  • Select the newly added JavaScript file maincode and in the Script Resource copy paste the following code snippet.
/*
This method checks if its an OData call by checking if the request path ends with $batch. 
Returns true if its an odata call else false.
*/
function isBatchCall(){
    return request.path.indexOf("$batch")>-1;
}

/*
This method returns the request count. For batch call it counts the no of request passed inside the batch call else returns 1
*/
function getRequestCount(){
    var numberOfRequest=1; 
    if (isBatchCall())
    {
      var pattern="Content-Type: application/http";
      var regExp = new RegExp(pattern, "gi"); 
      numberOfRequest = request.body.match(regExp) ? request.body.match(regExp).length : 1;
    }
    return numberOfRequest;
}

context.setVariable('sapapim.numberOfRequest', getRequestCount().toFixed(0));

 

The above snippet checks if the incoming request is an OData Batch request. For OData batch call the batch request payload is parsed and the individual request is read to set the counter, else the counter is set to a 1. This counter is then used to set a local flow variable sapapim.numberOfRequest ,  which is later  used as a reference in MessageWeight element of the Quota Policy.

Note that the above JavaScript is just a sample snippet and this snippet would have to be adjusted to handle all the edge cases of Batch calls.

 

  • Select PreFlow from the ProxyEndPoint  section and then click on the + button next to the JavaScript Policy available under the Extensions Policies segment.

 

  • In the Create policy screen specify the policy name say calculateMessageWeight and then click on the Add button.

 

  • Select the policy newly added calculateMessageWeight  policy then add the following policy snippet to invoke the maincode JavaScript file.
<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" xmlns='http://www.sap.com/apimgmt'>
	<ResourceURL>jsc://maincode.js</ResourceURL>
</Javascript

 

 

  • Select the policy calculateMessageWeight  and click on the <- button to move the policy execution before the applyRateLimit policy so that the message weight is calculated and set before the quota policy is enforced

 

  • Select and update the policy applyRateLimit with the following snippet.
<Quota async="false" continueOnError="true" enabled="true" type="calendar" xmlns="http://www.sap.com/apimgmt">
    <MessageWeight ref="sapapim.numberOfRequest"/>
 	<Allow count="5"/>
 	<Interval>1</Interval>
	<Distributed>true</Distributed>
 	<StartTime>2015-2-11 12:00:00</StartTime>
	<Synchronous>true</Synchronous>
 	<TimeUnit>minute</TimeUnit>
</Quota>

 

The MessageWeight property of the Quota policy is set to the flow variable sapapim.numberOfRequest which is calculated and set in the calculateMesageWeight JavaScript Policy.

 

  • Click on the Update button to save the Policy changes

 

  • Click on the Save button to save the changes to API Proxy.

 

 

With this we have successfully set the API rate limit using SAP Cloud API Management as described in the REST security protection in OWASP and following the rate limiting RFC standards for error handling and also handled the OData batch calls.

 

Finally testing the flow

 

  • Navigate to the Test tab from the hamburger icon

 

 

  • From the APIs list search for the API Proxy that you would like to test say GatewayServiceRestrictedAccess and then click the API to test.

 

 

  • Click on the Authentication: None link and select Basic Authentication to set the user credential to connect to the SAP Gateway ES4 system

 

 

  • Enter your user credential to the SAP Gateway ES4 system and click on the OK button

 

  • Since the OData batch request is a POST call, x-csrf-token handling would be required. Click on the Headers button. Enter x-csrf-token as header name and fetch as the header value and then click on the Send button

 

 

  • Click on the response headers tab, then copy the x-csrf-token value received from the server in the OData batch request call

 

 

  • Append /$batch to the API Proxy URL and then select POST method. In the x-csrf-token header value paste the x-csrf-token header response received from the server in previous call. Click on the + button next to the Headers and then add a new header named Content-Type with value set to multipart/mixed; boundary=batch. In the request body, paste the following batch request payload and then click on the Send button
--batch
Content-Type: application/http
Content-Transfer-Encoding: binary


GET ProductSet?$format=json&$top=2 HTTP/1.1


--batch
Content-Type: application/http
Content-Transfer-Encoding: binary


GET BusinessPartnerSet?$format=json&$top=2 HTTP/1.1


--batch--

The help document contains information about the Batch call processing for the SAP Gateway service.

The above batch request contains 2 GET calls and with the quota of 5 calls set, 2 batch request calls would be allowed in 1 minute quota period. Therefore click on the Send button three times and the on third time, 429 Too many Requests error would be received. This shows that instead of allowing 5 calls, the actual number of request sent from the caller in the batch request was used in the API rate limit calculation.

 

Further Reads

To report this post you need to login first.

Be the first to leave a comment

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

Leave a Reply