Rate Limiting
Rate-limiting allows you to set a maximum rate of requests for your API gateway. This is useful to enforce rate limits agreed with your clients and protect your downstream services.
The Zuplo Rate-Limit allows you to limit based on different attributes of the incoming request. For example, you might set a rate limit of 10 requests per second per user, or 20 requests per second for a given IP address.
The Zuplo rate-limiter also allows you to set a custom bucket name by which to effect a rate-limit using a function.
When a client reaches a rate limit - they will receive a 429
response code.
Configuration#
{
"name": "my-rate-limit-inbound-policy",
"policyType": "rate-limit-inbound",
"handler": {
"export": "RateLimitInboundPolicy",
"module": "$import(@zuplo/runtime)",
"options": {
"headerMode": "user",
"identifier": [
{
"export": "$import(./modules/my-module)",
"module": "default"
}
],
"mode": "strict",
"rateLimitBy": "user",
"requestsAllowed": 1000,
"throwOnFailure": false,
"timeWindowMinutes": 60
}
}
}
Options#
name
the name of your policy instance. This is used as a reference in your routes.policyType
the identifier of the policy. This is used by the Zuplo UI. Value should berate-limit-inbound
.handler/export
The name of the exported type. Value should beRateLimitInboundPolicy
.handler/module
the module containing the policy. Value should be$import(@zuplo/runtime)
.handler/options
The options for this policy:rateLimitBy
The identifying element of the request that enforces distinct rate limits. For example, you can limit by
user
,ip
,function
orall
- function allows you to specify a simple function to create a string identifier to create a rate-limit grouprequestsAllowed
The max number of requests allowed in the given time window
timeWindowMinutes
The time window in which the requests are rate-limited. The count restarts after each window expires
identifier
The function that returns dynamic configuration data. Used only with
rateLimitBy=function
export
used only with rateLimitBy=function. Specifies the export to load your custom bucket function, e.g.
default
,rateLimitIdentifier
.module
Specifies the module to load your custom bucket function, in the format
$import(./modules/my-module)
headerMode
Adds the retry-after header, defaults to true
throwOnFailure
If true, the policy will throw an error in the event there is a problem connecting to the rate limit service
mode
The mode of the policy. If set to
async
, the policy will check if the request is over the rate limit without blocking. This can result in some requests allowed over the rate limit.
Note you can have multiple instances of rate-limiting policies to use in combination. You should apply the longest duration timeWindow first, in order to the shortest duration time window.
Using a custom function
You can create a rate-limit bucket based on any property of a request using a
custom function that returns a CustomRateLimitDetails
object (which provides
the identifier used by the limiting system).
The CustomRateLimitDetails
object can be used to override the
timeWindowMinutes
& requestsAllowed
options.
This example would create a unique rate-limiting function based on the
customerId
parameter in routes (note it’s important that a policy like this is
applied to a route that has a /:customerId
parameter).
//module - ./modules/rate-limiter.ts
import { CustomRateLimitDetails, ZuploRequest } from "@zuplo/runtime";
export function rateLimitKey(
request: ZuploRequest,
context: ZuploContext,
policyName: string
): CustomRateLimitDetails {
context.log.info(
`processing customerId '${request.params.customerId}' for rate-limit policy '${policyName}'`
);
if (request.params.customerId === "43567890") {
// Override timeWindowMinutes & requestsAllowed
return {
key: request.params.customerId,
requestsAllowed: 100,
timeWindowMinutes: 1,
};
}
}
// config - ./config/policies.json
"export": "RateLimitInboundPolicy",
"module": "$import(@zuplo/runtime)",
"options": {
"rateLimitBy": "function",
"requestsAllowed": 2,
"timeWindowMinutes": 1,
"identifier": {
"module": "$import(./modules/rate-limiter)",
"export": "rateLimitKey"
}
}