info@yenlo.com
eng
Menu
WSO2 7 min

Custom Rate Limiting with WSO2 APIM

Our new blog delves into the world of custom rate limiting with WSO2 APIM. Understand how to create and test custom throttling policies tailored to your specific needs. Enhance your API management strategy with our expert insights and practical examples.

Saad Sahibjan - Integration Consultant
Saad Sahibjan
Integration Consultant
Lifecycle and publish the deployed API

WSO2 APIM is a leading platform for building, integrating and exposing digital services as managed APIs. In the digital landscape, APIs serves as the bridge between applications, enabling seamless data exchange and paving path for digital transformation. The WSO2 API Manager centrally operates in this ecosystem, offering a comprehensive suite of features and capabilities for managing the complete lifecycle of APIs.

One of the major features of WSO2 APIM is rate limiting. Rate limiting of APIs is a critical aspect of API management that involves limiting the number of requests that can be made to an API during a given period. The primary purpose of rate limiting is to prevent abuse, protect server resources, ensure fair usage, monetization and maintain the overall quality of service for API consumers.

There are different types and levels of rate limiting supported by WSO2. Custom rate limiting is where it allows system administrators to define dynamic custom policies to tailor your API rate limiting rules to specific use cases and requirements. It’s important to note that custom rate-limiting policies are globally applied to all tenants. Custom rate limiting policies are defined by Siddhi query language. Hence, policies can be written by using Siddhi queries.

A custom policy consists of two major parts: the key template and Siddhi query. There are set of allowed keys which can be used as key templates. Multiple keys can be used separated by a colon (:), where each key must start with the prefix $. Allowed keys in the key template are as below,

  • $resourceKey
  • $userId
  • $apiContext
  • $apiVersion
  • $appTenant
  • $apiTenant
  • $appId
  • $clientIp

In the Siddhi query, we write the actual policy. In the query we must set a throttle key. If there is a mismatch between the throttle key and the key template the request will not be throttled. Hence throttle key in the Siddhi query should match the key template.

Create and test a custom throttling policy

For this purpose, I will be using the latest WSO2 APIM 4.2 running in my local. If you do not know how, read one of our blogs which explains how to run WSO2 products on Linux/Windows/Mac.

Once WSO2 server is up and running we can access the portals with the below URLs,

  • Publisher portal – https://localhost:9443/pubisher
  • Developer portal – https://localhost:9443/devportal
  • Admin portal – https://localhost:9443/admin

Before creating a custom throttling policy, an API must be created and subscribed, to ensure that the API undergoes testing for throttling in accordance with the customized throttling policy.

Create an API

A new API is created in the publisher portal with the required resources, then it is deployed and published. Hence, a custom throttling policy can be created to throttle the API.

  • Go to Publisher portal – https://localhost:9443/pubisher
  • Create an API with the following details
Create an API
  • Go to Resources and delete the generated resources and add two GET resources for posts and todos as below,
Resources
  • Go to Deployments and deploy the created API
Deployments and deploy the created API
  • Go to Lifecycle and publish the deployed API
Lifecycle and publish the deployed API

Subscribe to the API

An application is needed to be created in the developer portal and subscribed to the created API for us to generate a token and invoke the API resources.

  • Go to Developer portal – https://localhost:9443/devportal
  • Create an application
Create an application
  • Subscribe to the API
Subscribe to the API
  • Generate a token
Generate a token

Access the API

For accessing the API, any REST client or CURL can be used. In this case, I’m using Postman to invoke the API resources with the generated token to make sure the API resources are working as expected.

  • Call the /posts API by using the generated token in the previous step
Call the posts API
  • Call the /todos API by using the generated token in the previous step
Call the todos API by using the generated token in the previous step

Both the APIs are working as expected.

Create a custom throttling policy

Let’s create a custom throttling policy to throttle the posts endpoint when more than 5 requests are made within a minute.

  • Go to Admin portal – https://localhost:9443/admin
  • Select Custom Policies and click Define
Custom Policies
  • Create policy with below details,
Create policy
Key Template: $resourceKey
Siddhi Query:
FROM
  RequestStream
SELECT
  userId,
  (resourceKey == '/test/v1/v1/posts:GET') AS isEligible,
  resourceKey as throttleKey
INSERT INTO
  EligibilityStream;
FROM
  EligibilityStream [ isEligible == true ] # throttler: timeBatch(1 min)
SELECT
  throttleKey,
  (count(userId) >= 5) as isThrottled,
  expiryTimeStamp
group by
  throttleKey
INSERT
  ALL EVENTS into ResultStream;

As per the policy,

  • KeyTemplate has the value $resourceKey which implies the throttling should be done based on the resource path
  • In SiddhiQuery,
    • resourceKey = /test/v1/v1/posts:GET – throttling is to be check for the endpoint /test/v1/v1/posts which is a GET resource.
    • resourceKey as throttleKey – is where the value of KeyTemplate will be same as the value of throttleKey
    • timeBatch(1 min) — is the throttling policy time period.
    • count(userId) >= 5) as isThrottled — is the throttling request count checker (5 requests for each userID).

Therefore, the summary of above Siddhi query is that this policy allows a user to send only 5 requests per 1 minute for the GET resource /test/v1/v1/posts and then it will throttle the request.

Test custom throttling policy

Now we must call the posts endpoint more than 5 times to check if the request gets throttled. When it is tested by calling the endpoint more than 5 times it gives the following message with the status code 429 (too many requests),

Test custom throttling policy

As per the above, custom throttling works as expected and this custom policy has no affect for the other endpoint todos. If todos endpoint is called more that 5 times, it will continue to work as the custom policy is created only to throttle the posts resource.

Additional Policy – Throttle a specific API resource for a specific user

This is a policy to throttle a specific API resource which is the ‘/posts’ resource for a specific user called ‘saad’ under the super tenant.

Key Template: $userId:$resourceKey

Siddhi Query:

FROM
  RequestStream
SELECT
  userId,
  (
    userId == 'saad@carbon.super'
    and resourceKey == '/test/v1/v1/posts:GET'
  ) AS isEligible,
  str: concat('saad@carbon.super', ':', '/test/v1/v1/posts:GET') as throttleKey
INSERT INTO
  EligibilityStream;
FROM
  EligibilityStream [ isEligible == true ] # throttler: timeBatch(1 min)
SELECT
  throttleKey,
  (count(throttleKey) >= 5) as isThrottled,
  expiryTimeStamp
group by
  throttleKey
INSERT
  ALL EVENTS into ResultStream;

As per the above query,

  • (userId == ‘saad@carbon.super‘ and resourceKey == ‘/test/v1/v1/posts:GET’ ) AS isEligible – is where the specific userId and resource path is selected for throttling
  • str: concat(‘saad@carbon.super’, ‘:’, ‘/test/v1/v1/posts:GET’) as throttleKey – specific userId and the resource path are concatanated and set as the throttle key to which will then be same as the key template.
  • timeBatch(1 min) — is the throttling policy time period.
  • count(throttleKey) >= 5) as isThrottled – is the throttling request count checker (5 requests for the throttle key where 5 requests allowed for the specific user for the specific resource).

Therefore, the summary of above Siddhi query is that this policy allows the user saad@carbon.super to send only 5 requests per 1 minute for the GET resource /test/v1/v1/posts and then it will throttle the request. And the throttling will not apply for any other resources and also not for any other users for this specific resource.

Additional Policy – Throttle API requests for all the users other than the super admin user

This is a policy to throttle API requests for any users other than the super admin user. Hence, the request will get throttled for any user unless the user is an admin in the super tenant.

Key Template: $userId
Siddhi Query:
FROM
  RequestStream
SELECT
  userId,
  (userId != 'admin@carbon.super') AS isEligible,
  userId as throttleKey
INSERT INTO
  EligibilityStream;
FROM
  EligibilityStream [ isEligible == true ] # throttler: timeBatch(1 min)
SELECT
  throttleKey,
  (count(userId) >= 5) as isThrottled,
  expiryTimeStamp
group by
  throttleKey
INSERT
  ALL EVENTS into ResultStream;

As per the above query,

  • (userId != ‘admin@carbon.super’) AS isEligible – is where the specific userId selected for throttling (in this case it is all the users except for the super admin user)
  • userId as throttleKey – userId is set as the throttle key, which will then be same as the key template.
  • timeBatch(1 min) — is the throttling policy time period.
  • count(userId) >= 5) as isThrottled – is the throttling request count checker (5 requests for each userID).

Therefore, the summary of above Siddhi query is that this policy allows the super admin user (admin@carbon.super) to send any number of requests and any other user can send only 5 requests per 1 minute for any resources then it will throttle the requests.

Conclusion

Rate limiting is a primary feature in any API management platform. With custom rate limiting you/it can offer several advantages, particularly when you have specific use cases and requirements that go beyond standard rate limiting policies. It provides fine grained controls on throttling based on API context, version, resource path, user ID etc. Having such control allows for adjustments based on evolving conditions or business needs. Custom rate limiting can support personalized experiences for users. You can tailor rate limits to individual users’ behaviour, providing a smoother and more responsive experience for your most active users.

For industries with specific compliance requirements, custom rate limiting can help ensure that your API usage adheres to regulatory standards. You can implement rate limits that align with compliance mandates. It’s important to note that while custom rate limiting offers these advantages, it also requires careful planning, testing, and ongoing monitoring. Implementing complex rate limiting logic should be done thoughtfully to avoid unintentional service disruptions or overly restrictive policies. Additionally, consider the scalability of your custom rate limiting solution to accommodate growing API usage.

eng
Close