This example demonstrates how to invoke the Rate Limit policy programmatically and customize the 429 (Too Many Requests) response body with additional context information like rate limit details.
By default, Zuplo's rate limit policy returns a standard 429 response. This example shows how to intercept that response and add useful information like the rate limit configuration, remaining requests, and retry timing.
Prerequisites
- A Zuplo account. You can sign up for free.
Working with this Example
Locally
Working locally is the best way to explore and understand the code for this example. You can get a local version by using the Zuplo CLI:
Then, in the project directory run the following commands:
Deploy this example to Zuplo
It is also possible to deploy this example directly to your Zuplo account and work with it via the Zuplo Portal. You can do this by clicking the Deploy to Zuplo button anywhere on this page.
How It Works
This example uses two key techniques:
1. Programmatic Policy Invocation
Instead of applying the rate limit policy directly in the route configuration, a custom policy invokes it programmatically using context.invokeInboundPolicy():
This allows the custom policy to intercept the response and modify it.
2. Custom 429 Response
When the rate limit is exceeded, the custom policy creates a detailed error response using HttpProblems.tooManyRequests():
3. ContextData for Passing Information
The rate limit key function stores the rate limit configuration in ContextData, making it available for the custom response:
Project Structure
Configuration
Rate Limit Settings
The rate limit is configured in config/policies.json:
| Option | Value | Description |
|---|---|---|
requestsAllowed | 2 | Maximum requests allowed |
timeWindowMinutes | 1 | Time window for the limit |
rateLimitBy | "function" | Use custom function for rate limit key |
Custom Rate Limit Key
The rateLimitKey function in modules/rate-limiting.ts determines how requests are grouped for rate limiting:
Testing the Example
Make multiple requests to trigger the rate limit:
Expected 429 Response
When rate limited, you'll receive a detailed JSON response:
Common Customizations
- Per-user rate limits: Change the key to
request.user.subafter adding authentication - Different limits per tier: Use
request.user.data.tierto set different limits for different customer tiers - Add retry-after info: Include timing information in the custom response
- Log rate limit events: Add logging when rate limits are hit
Key Concepts Demonstrated
context.invokeInboundPolicy()- Programmatically invoke other policiesContextData- Pass data between policy functionsHttpProblems- Create RFC 7807 compliant error responsesCustomRateLimitDetails- Type-safe rate limit configuration