https://github.com/soontao/cds-rate-limit
rate limiter for CAP CDS nodejs runtime
https://github.com/soontao/cds-rate-limit
cap cds ddos rate sap
Last synced: 3 months ago
JSON representation
rate limiter for CAP CDS nodejs runtime
- Host: GitHub
- URL: https://github.com/soontao/cds-rate-limit
- Owner: Soontao
- License: other
- Created: 2022-03-10T02:27:39.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-10-29T14:06:37.000Z (12 months ago)
- Last Synced: 2024-10-29T17:14:12.380Z (12 months ago)
- Topics: cap, cds, ddos, rate, sap
- Language: TypeScript
- Homepage:
- Size: 1.09 MB
- Stars: 2
- Watchers: 2
- Forks: 1
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# CDS Rate Limit
> apply `rate limit` pattern to CAP nodejs application
[](https://www.npmjs.com/package/cds-rate-limit)
[](https://github.com/Soontao/cds-rate-limit/actions/workflows/nodejs.yml)
[](https://codecov.io/gh/Soontao/cds-rate-limit)[](https://sonarcloud.io/summary/new_code?id=Soontao_cds-rate-limit)
[](https://sonarcloud.io/summary/new_code?id=Soontao_cds-rate-limit)
[](https://sonarcloud.io/summary/new_code?id=Soontao_cds-rate-limit)## Get Started
`package.json`
```json
{
"cds": {
"plugins": ["cds-rate-limit"]
}
}
````cds definition`
```groovy
using {cuid, managed} from '@sap/cds/common';
@path : '/sample3'
service Sample3Service {// define rate limit for entity CRUD events and actions
// accepts 1000 requests in 120 seconds
// other requests will be rejected by HTTP 429 status
@cds.rate.limit : {
duration : 120,
points : 1000,
}
entity People : cuid, managed {
Name : String(255);
Age : Integer;
}// share global quota
entity Other: cuid, managed {
Name : String(255);
}
}
```## Headers
- `Retry-After` - reset after seconds later
- `X-RateLimit-Reset` - reset timestamp (unix timestamp)
- `X-RateLimit-Limit` - total quota for each window
- `X-RateLimit-Remaining` - remaining quota for current window## RateLimiter Hierarchy
> the `RateLimiter` configuration will apply restriction by order, if you do not annotate `@cds.rate.limit` on entity/action/function level, it will share the quota of the global `RateLimiter`
1. Event/Action/Function
2. Entity
3. Service
4. Global## Options
- `keyParts`: use to generated the key
- `remote_ip` - req.\_.req.ip - please ref [express document](http://expressjs.com/en/guide/behind-proxies.html) to setup `trust proxy`
- `user_id` - ctx.user.id
- `tenant` - ctx.tenant
- `points`: quota for each key (user, ip, tenant or combined)
- `duration`: quota for each key in duration (reset duration for quota)### Default Global Options
**if there is no annotation on CDS Service/Entity/Action/Function, it will use the global configuration**
```js
{
impl: "memory", // use in-memory
keyParts: ["tenant"], // generate key from tenant
keyPrefix: GLOBAL_RATE_LIMITER_PREFIX, // default prefix
duration: 60, // 60 seconds
points: 200 * 60, // 200 requests per seconds// for anonymous requests (without authorization header)
anonymous: {
// per seconds per remote ip allow 1000 requests
keyPrefix: GLOBAL_ANONYMOUS_RATE_LIMITER_PREFIX,
duration: 10,
points: 10 * 100,
},
}
```### Example - Memory
> configuration global default configuration, each user could call API 6000 times in 1 minute duration
```json
{
"cds": {
"plugins": ["cds-rate-limit"],
"config": {
"rateLimit": {
"impl": "memory",
"duration": 60,
"points": 6000,
"keyParts": ["user_id"]
}
}
}
}
```### Example - Redis
> each user in each tenant could use the API 300 times in 5 seconds duration
```json
{
"cds": {
"plugins": [
"cds-rate-limit"
],
"config": {
"rateLimit": {
"impl": "redis",
"duration": 5,
"points": 300,
"keyParts": ["tenant", "user_id"],
"redisOptions": {
"enableOfflineQueue": false
}
}
}
}
}
```- for redis connection options, please check [ioredis document](https://www.npmjs.com/package/ioredis) or [RedisOptions type](https://github.com/luin/ioredis/blob/6f1ab9f/lib/redis/RedisOptions.ts#L188)
## Features
- [x] Global Rate Limit
- [x] Event Rate Limit
- [x] Inner event ignore
- [x] Anonymous Request Rate Limit
- [x] Custom key
- [ ] Global Env Configuration
- [x] Redis store
- [ ] Dynamic quota configuration
- [ ] Sampling store to reduce remote store network consumption## ToDo
- [x] How to process anonymous requests
- [ ] Documents for microservice
- [ ] Performance## [CHANGELOG](./CHANGELOG.md)
## [LICENSE](./LICENSE)