Skip to content
This repository was archived by the owner on Sep 17, 2024. It is now read-only.

Commit 5dfeff2

Browse files
committed
chore: add docs to core modules
1 parent 0f251d4 commit 5dfeff2

File tree

4 files changed

+898
-2
lines changed

4 files changed

+898
-2
lines changed

modules/rate_limit/README.md

+172
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Rate Limit
2+
3+
Rate limiting is a crucial aspect of managing your game's backend to prevent abuse and ensure fair usage of your resources. The `rate_limit` module in Open Game Backend provides an easy way to implement rate limiting for your scripts.
4+
5+
## What is Rate Limiting?
6+
7+
Rate limiting restricts the number of requests a client can make to your backend within a specified time period. This helps to:
8+
9+
1. Prevent abuse and potential DoS attacks
10+
2. Ensure fair usage of resources among all users
11+
3. Manage server load and maintain performance
12+
13+
## Using the Rate Limit Module
14+
15+
The `rate_limit` module provides two main scripts:
16+
17+
1. `throttle`: For general-purpose rate limiting
18+
2. `throttle_public`: Specifically designed for rate limiting public scripts
19+
20+
Let's focus on `throttle_public` as it's the recommended method for rate limiting public scripts.
21+
22+
### Throttling Public Scripts
23+
24+
To rate limit a public script, you can use the `throttle_public` script at the beginning of your script. Here's how to use it:
25+
26+
<CodeGroup>
27+
```typescript scripts/my_public_script.ts
28+
import { ScriptContext } from "../module.gen.ts";
29+
30+
export interface Request {
31+
// Your request parameters here
32+
}
33+
34+
export interface Response {
35+
// Your response type here
36+
}
37+
38+
export async function run(
39+
ctx: ScriptContext,
40+
req: Request
41+
): Promise<Response> {
42+
// Apply rate limiting
43+
await ctx.modules.rateLimit.throttlePublic({});
44+
45+
// Your script logic here
46+
// ...
47+
48+
return {
49+
// Your response here
50+
};
51+
}
52+
```
53+
</CodeGroup>
54+
55+
The `throttlePublic` script automatically uses the client's IP address for rate limiting. By default, it allows 20 requests per 5 minutes (300 seconds) for each IP address.
56+
57+
### Customizing Rate Limits
58+
59+
You can customize the rate limit by passing parameters to `throttlePublic`:
60+
61+
<CodeGroup>
62+
```typescript scripts/my_custom_rate_limited_script.ts
63+
export async function run(
64+
ctx: ScriptContext,
65+
req: Request
66+
): Promise<Response> {
67+
// Custom rate limit: 5 requests per 1 minute
68+
await ctx.modules.rateLimit.throttlePublic({
69+
requests: 5,
70+
period: 60
71+
});
72+
73+
// Your script logic here
74+
// ...
75+
}
76+
```
77+
</CodeGroup>
78+
79+
## Best Practices for Rate Limiting
80+
81+
1. **Only Rate Limit Public Scripts**: Apply rate limiting to public scripts that are directly accessible by clients. Internal scripts called by other modules typically don't need rate limiting.
82+
83+
2. **Choose Appropriate Limits**: Set rate limits that balance protection against abuse with legitimate usage patterns. Consider your game's requirements and user behavior.
84+
85+
3. **Use `throttle_public` for Client-Facing Scripts**: The `throttle_public` script is designed to work with client IP addresses automatically, making it ideal for public-facing endpoints.
86+
87+
4. **Consistent Application**: Apply rate limiting consistently across all public endpoints to prevent attackers from finding unprotected routes.
88+
89+
5. **Monitor and Adjust**: Regularly review your rate limits and adjust them based on real-world usage and any issues that arise.
90+
91+
6. **Inform Users**: When a rate limit is exceeded, return a clear error message to the client so they understand why their request was blocked.
92+
93+
7. **Consider Different Limits for Different Actions**: Some actions might require stricter rate limits than others. For example:
94+
95+
<CodeGroup>
96+
```typescript scripts/login.ts
97+
export async function run(ctx: ScriptContext, req: Request): Promise<Response> {
98+
// Stricter rate limit for login attempts
99+
await ctx.modules.rateLimit.throttlePublic({
100+
requests: 5,
101+
period: 300 // 5 minutes
102+
});
103+
104+
// Login logic here
105+
// ...
106+
}
107+
```
108+
109+
```typescript scripts/fetch_game_state.ts
110+
export async function run(ctx: ScriptContext, req: Request): Promise<Response> {
111+
// More lenient rate limit for fetching game state
112+
await ctx.modules.rateLimit.throttlePublic({
113+
requests: 60,
114+
period: 60 // 1 minute
115+
});
116+
117+
// Fetch game state logic here
118+
// ...
119+
}
120+
```
121+
</CodeGroup>
122+
123+
8. **Handle Rate Limit Errors Gracefully**: In your client-side code, be prepared to handle rate limit errors and potentially implement exponential backoff for retries.
124+
125+
## Example: Rate Limited Leaderboard Fetch
126+
127+
Here's an example of how you might implement a rate-limited public script for fetching a game leaderboard:
128+
129+
<CodeGroup>
130+
```typescript scripts/fetch_leaderboard.ts
131+
import { ScriptContext } from "../module.gen.ts";
132+
133+
export interface Request {
134+
gameMode: string;
135+
limit: number;
136+
}
137+
138+
export interface Response {
139+
leaderboard: LeaderboardEntry[];
140+
}
141+
142+
interface LeaderboardEntry {
143+
username: string;
144+
score: number;
145+
}
146+
147+
export async function run(
148+
ctx: ScriptContext,
149+
req: Request
150+
): Promise<Response> {
151+
// Apply rate limiting: 10 requests per minute
152+
await ctx.modules.rateLimit.throttlePublic({
153+
requests: 10,
154+
period: 60
155+
});
156+
157+
// Validate request
158+
if (req.limit > 100) {
159+
throw new Error("Limit cannot exceed 100");
160+
}
161+
162+
// Fetch leaderboard logic here (example)
163+
const leaderboard = await ctx.modules.gameData.getLeaderboard(req.gameMode, req.limit);
164+
165+
return {
166+
leaderboard
167+
};
168+
}
169+
```
170+
</CodeGroup>
171+
172+
In this example, we've applied a rate limit of 10 requests per minute to the leaderboard fetch script. This allows frequent updates for players while still protecting the backend from excessive requests.

0 commit comments

Comments
 (0)