You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: pages/nestjs-api-gateway/index.md
+48-3Lines changed: 48 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -53,9 +53,11 @@ Import the `ApiGatewayModule` and use the `forRoot` method to configure the API
53
53
showExtensions: false,
54
54
},
55
55
throttler: {
56
-
globalRateLimit: 60,
57
-
isEnable: true,
58
-
globalRateLimitTTL: 60
56
+
globalIpRateLimit: 120,
57
+
globalIpRateLimitTTL: 60,
58
+
globalCustomRateLimit: 60,
59
+
globalCustomRateLimitTTL: 60,
60
+
isEnable: true
59
61
}
60
62
})
61
63
],
@@ -133,6 +135,49 @@ index(): string {
133
135
}
134
136
```
135
137
138
+
#### Global rate limits
139
+
The throttler enforces two independent global limits on every request:
140
+
141
+
-**`globalIpRateLimit` / `globalIpRateLimitTTL`** — always bucketed by `request.ip`. This is a DDoS / abuse baseline that does **not** go through `keyResolver` and is **not** skipped when the resolver returns an empty value.
142
+
-**`globalCustomRateLimit` / `globalCustomRateLimitTTL`** — bucketed by whatever `keyResolver` returns (or `request.ip` if no resolver is configured). Skipped entirely when the resolver returns an empty value.
143
+
144
+
A request is rejected as soon as either limit is exceeded.
145
+
146
+
#### Custom rate-limit key
147
+
By default the custom limit buckets requests by `request.ip`. To bucket by something else (authenticated user id, tenant id, API key, etc.), supply a `keyResolver` callback in the throttler options. The callback receives `{ request, routerDetail }` and returns the string to use as the bucket identity.
148
+
149
+
```typescript
150
+
ApiGatewayModule.forRoot({
151
+
// ... other options ...
152
+
throttler: {
153
+
globalIpRateLimit: 120,
154
+
globalIpRateLimitTTL: 60,
155
+
globalCustomRateLimit: 60,
156
+
globalCustomRateLimitTTL: 60,
157
+
isEnable: true,
158
+
keyResolver: ({ request }) => {
159
+
const userId =request.headers['auth-user-id'];
160
+
returntypeofuserId==='string'&&userId.length>0
161
+
?`user:${userId}`
162
+
:`ip:${request.ip}`;
163
+
}
164
+
}
165
+
})
166
+
```
167
+
168
+
**Skip the custom limit for selected requests** by returning an empty value (`null`, `undefined`, `''`, or a whitespace-only string). The throttler then bypasses both the custom global limit and any per-endpoint `@ApiRateLimit` rules without incrementing their counters. The IP-based global limit still applies.
169
+
170
+
```typescript
171
+
keyResolver: ({ request, routerDetail }) => {
172
+
if (request.url==='/healthz') returnnull; // skip health checks
173
+
if (routerDetail.operationId==='InternalProbeController_ping') returnnull; // skip by operation id
The same identity is used for the custom global limit and for any per-endpoint `@ApiRateLimit` rule. Resolvers may be asynchronous. If the resolver throws, the error propagates through the gateway's existing exception pipeline (no silent allow, no silent deny). If `keyResolver` is omitted, the custom limit falls back to `request.ip` (matching the IP limit's bucketing key). See `specs/002-throttler-key-callback/quickstart.md` for the full walkthrough.
180
+
136
181
## Support:
137
182
138
183
If you encounter any issues, have questions, or need assistance with the API Gateway, please contact the development team
0 commit comments