Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(providers): add option to apply ratelimiting over single API #68

Merged
merged 1 commit into from
Mar 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,16 @@ For redis datasource, you have to pass the name of a loopback4 datasource
```ts
this.bind(RateLimitSecurityBindings.CONFIG).to({
name: 'redis',
type:'RedisStore'
type: 'RedisStore',
});
```


For memcache datasource

```ts
this.bind(RateLimitSecurityBindings.CONFIG).to({
client: memoryClient,
type:'MemcachedStore'
type: 'MemcachedStore',
});
```

Expand Down Expand Up @@ -75,6 +74,25 @@ this.bind(RateLimitSecurityBindings.CONFIG).to({
});
```

## EnabledbyDefault

enabledByDefault option in Config Binding will provide a configurable mode.
When its enabled (default value is true),it will provide a way to
ratelimit all API's except a few that are disabled using a decorator.

To disable ratelimiting for all APIs except those that are enabled using the decorator,
you can set its value to false in config binding option.

```
this.bind(RateLimitSecurityBindings.CONFIG).to({
name: 'redis',
type: 'RedisStore',
max: 60,
keyGenerator: rateLimitKeyGen,
enabledByDefault:false
});
```

- The component exposes a sequence action which can be added to your server sequence class. Adding this will trigger ratelimiter middleware for all the requests passing through.

```ts
Expand Down
9 changes: 8 additions & 1 deletion src/providers/ratelimit-action.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export class RatelimitActionProvider implements Provider<RateLimitAction> {
}

async action(request: Request, response: Response): Promise<void> {
const enabledByDefault = this.config?.enabledByDefault ?? true;
const metadata: RateLimitMetadata = await this.getMetadata();
const dataStore = await this.getDatastore();
if (metadata && !metadata.enabled) {
Expand Down Expand Up @@ -54,6 +55,12 @@ export class RatelimitActionProvider implements Provider<RateLimitAction> {
resolve();
});
});
await promise;
if (enabledByDefault === true) {
await promise;
} else if (enabledByDefault === false && metadata && metadata.enabled) {
await promise;
} else {
return Promise.resolve();
yeshamavani marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
8 changes: 6 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ export interface DataSourceConfig {
uri?: string;
collectionName?: string;
}

export interface RateLimitConfig {
enabledByDefault?: boolean;
}
export interface RateLimitAction {
(request: Request, response: Response): Promise<void>;
}

export type RateLimitOptions = Writable<Partial<Options>> & DataSourceConfig;
export type RateLimitOptions = Writable<Partial<Options>> &
DataSourceConfig &
RateLimitConfig;

/**
* Rate limit metadata interface for the method decorator
Expand Down