Policies
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": {
"rateLimitBy": "ip",
"requestsAllowed": 2,
"timeWindowMinutes": 1
}
}
}
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)
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"
}
}