# @beignet/provider-rate-limit-upstash 中文文档

规范地址：https://npmcn.com/package/%40beignet/provider-rate-limit-upstash/

版本：0\.0\.65
npm 元数据更新时间：2026-11-07T23:22:54.437Z
中文译文更新时间：2026-11-07T23:49:24.245Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40beignet/provider-rate-limit-upstash
原文对照：https://npmcn.com/package/%40beignet/provider-rate-limit-upstash/?lang=original
项目主页：https://github.com/taylorbryant/beignet#readme
源码仓库：https://github.com/taylorbryant/beignet

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：69.2 kB，9 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.12\.0
- 运行依赖：1 个
- peer 依赖：@beignet/core \>=0\.0\.3 \<1\.0\.0，@upstash/redis ^1\.0\.0，@upstash/ratelimit ^2\.0\.0
- 首次发布：2026-05-26T16:50:08.168Z
- 最新版本发布：2026-11-07T23:22:54.263Z
- 近 30 天下载量：1981（2026-10-08 至 2026-11-06，npm 官方下载统计）
- 已发布版本数：65（近 12 个月 65 个）

## 中文简介

Beignet 基于 Upstash 的费率限制提供者 - 使用 Upstash Redis 添加费率限制端口

## 安装

```sh
npm install @beignet/provider-rate-limit-upstash
```

也可以使用：`pnpm add @beignet/provider-rate-limit-upstash`、`yarn add @beignet/provider-rate-limit-upstash`、`bun add @beignet/provider-rate-limit-upstash`

## README

# @beignet/professor-rate-limit-upstash (英语)

> **运行时间 :** Beignet需要Node.js 22.12或更新. Bun是可选的.

> \[叹息\] Beignet是实验性的α软件. 这个 `0.0.x` 包行为早期 评估,且在框架结算时,API可能在发布之间发生变化.

向上支撑 `RateLimitPort` beignet 应用程序的提供者.

提供者安装 `ctx.ports.rateLimit` 使用 [升起雷迪丝](https://upstash.com/) 财务报告和审定财务报表 [@ upstash/ 速率限制](https://github.com/upstash/ratelimit)。 。 。 .

`createUpstashRateLimitProvider(...)` 返回稳定 `UpstashRateLimitProvider` 类型. `UpstashRateLimitConfig` 说明 经验证的配置; Zod schema 仍为内部.

## 特征

-   执行标准 `RateLimitPort` 接口.
-   使用 Upstash Redis REST API,所以它不方便服务器.
-   支持每个请求带有可配置密钥前缀的动态限制.
-   支持固定窗口和滑动窗口算法通过 `UPSTASH_ALGORITHM`。 。 。 .
-   约束依赖决定,在5秒后默认失败.
-   显示只读的准备状态检查 `ctx.ports.upstash`。 。 。 .
-   Emits devetools 事件为允许, 被屏蔽和失败的点击 .

## 安装

```bash
bun add @beignet/provider-rate-limit-upstash @beignet/core @upstash/redis @upstash/ratelimit
```

## 配置

设定这些环境变量 :

| 变量 | 需求 | 说明 | 示例 |
| --- | --- | --- | --- |
| `UPSTASH_REDIS_REST_URL` | 对 | 您的 Upstash Redis 更新 URL | `https://us1-properly-ancient-12345.upstash.io` |
| `UPSTASH_REDIS_REST_TOKEN` | 对 | 您的上方Redis REST 标志 | `AXXXeyJpZCI6IjEy...` |
| `UPSTASH_PREFIX` | 没有 | 速率限制密钥的密钥前缀( 默认 : `beignet:ratelimit`(中文(简体) ) | `myapp:ratelimit` |
| `UPSTASH_ALGORITHM` | 没有 | 利率限制算法, `fixed-window` 或者说 `sliding-window` (默认 : `fixed-window`(中文(简体) ) | `sliding-window` |
| `UPSTASH_TIMEOUT_MS` | 没有 | 最大等待时间 : `1` 结束 `2147483647` 毫秒( 默认值 : `5000`(中文(简体) ) | `2500` |
| `UPSTASH_TIMEOUT_POLICY` | 没有 | `fail-closed` 拒绝超时检查; `fail-open` 允许它们并记录退化的强制执行(违约: `fail-closed`(中文(简体) ) | `fail-closed` |

### 选择一个算法

-   `fixed-window` (默认)是最便宜的选择:每个窗口一个计数器. 这个 由于客户端可以花一整张 在一个窗口后端和下一个窗口开始时再次限制.
-   `sliding-window` 平滑这些边界,以重压上一个 窗口进入当前之一,但每击一次要花费略多一点的Redis工作.

切换算法改变Redis中计数器的键法,所以在飞行中 窗口在更改时有效重置 `UPSTASH_ALGORITHM`。 。 。 .

### 获取 Upstash 证书

1.  报名到 [上图](https://upstash.com/)
2.  创建一个新的 Redis 数据库
3.  导航到数据库细节页面
4.  从“ REST API” 部分复制 REST URL 和 REST 令牌

## 设置

在 Beignet 启动程序中,安装并电线连接端口:

```bash
bun beignet provider add rate-limit-upstash
bun install
```

上方设置 Upstash 环境变量 。 预设扩展了已有的 供应商注册和应用程序端口接线。 添加 `createRateLimitHooks<AppContext>()` 从 `@beignet/core/server` 中的现有钩子列表 `server/index.ts` 改为 执行合同元数据。 保存启动者的认证, 上下文, 其他钩子, 和提供者.

手工提供者注册,导入 `createUpstashRateLimitProvider` 从此包中添加 `createUpstashRateLimitProvider()` 给您的提供者 列表中选择一个选项。 跟着 [费率限制指南](https://beignetjs.com/rate-limiting) 页:1 服务器补丁和校验步骤.

赤裸裸的 `createRateLimitHooks<AppContext>()` 呼叫覆盖 `global` 财务报告和审定财务报表 `user` 范围限制。 申报合同 `rateLimit: { scope: "ip" }` 需要一个 明确的服务器级别 `trustedProxy.clientIp`本地钩 `trustedProxy.clientIp`, (中文(简体) ), `ipSource`,或 `earlyKey` 选项 : `createServer(...)` 启动时失败, 否则无法默默指定 所有不明的交通量 在一个合同范围桶。 偏好服务器级别 `trustedProxy: { clientIp: "x-forwarded-for-last" }` 在信任的倒数后面 代理或 `trustedProxy: { clientIp: "cf-connecting-ip" }` 用于平台 头. 仅对故意的覆没使用钩-局部选项,或 `ipSource: "none"` 选择每个合同使用一个未知客户桶.

默认密钥包括合同名称, 因此不相关的合同不消耗 彼此的极限 用户范围失败 `AuthUnauthorizedError` 除非 路由钩解决一个用户演员。 习惯 `key` 或者说 `earlyKey` 拥有完整 buck 键并应当包括路由身份,除非交叉路由聚合 有意为之.

`beignet doctor --strict` 安装 Upstash 费率限制供应商的检查 登记在 `server/providers.ts` 还有 `UPSTASH_REDIS_REST_URL`编号 :`UPSTASH_REDIS_REST_TOKEN` 存在于应用程序内 示例或配置.

使用 `createUpstashRateLimitProvider(...)` 如果您要直接通过配置 而不是读 `UPSTASH_*` (原始内容存档于2018-10-21). Env vars. 选项覆盖 env 衍生值 :

```ts
import { createUpstashRateLimitProvider } from "@beignet/provider-rate-limit-upstash";

export const providers = [
  createUpstashRateLimitProvider({
    redisRestUrl: secrets.upstashRedisRestUrl,
    redisRestToken: secrets.upstashRedisRestToken,
    prefix: "myapp:ratelimit",
    algorithm: "sliding-window",
    timeoutMs: 2500,
    timeoutPolicy: "fail-closed",
  }),
];
```

通话 `createUpstashRateLimitProvider()` 没有选项 配置 .

### 直接适配器

使用 `createUpstashRateLimit(...)` 当应用程序已经拥有 Upstash Redis 时 客户端 :

```ts
import { Redis } from "@upstash/redis";
import { createUpstashRateLimit } from "@beignet/provider-rate-limit-upstash";

const client = Redis.fromEnv();
const rateLimit = createUpstashRateLimit({
  client,
  prefix: "myapp:ratelimit",
  algorithm: "sliding-window",
  timeoutMs: 2500,
  timeoutPolicy: "fail-closed",
});
```

直接工厂默认为相同的 `beignet:ratelimit` 前缀和 `fixed-window` 算法作为提供者。 它没有读取环境变量 并且不拥有客户生命周期。 过 `instrumentation` 保留 直接接线的提供者事件.

## 直接使用

供应商注册后,可以在钩子中使用速率限制端口, 政策,或使用案例:

```ts
// Example app-specific policy that rate limits by IP address
async function checkIpRateLimit(ctx: AppContext) {
  const result = await ctx.ports.rateLimit.hit({
    key: `ip:${ctx.ip}`,
    limit: 100,
    windowSec: 60, // 100 requests per 60 seconds
  });

  if (!result.allowed) {
    return {
      status: 429,
      headers: {
        "X-RateLimit-Limit": "100",
        "X-RateLimit-Remaining": String(result.remaining ?? 0),
        "X-RateLimit-Reset": result.resetAt?.toISOString() ?? "",
        "Retry-After": String(result.retryAfterSeconds ?? 0),
      },
      body: {
        code: "TOO_MANY_REQUESTS",
        message: "Rate limit exceeded. Please try again later.",
      },
    };
  }

  // Request is allowed
  return undefined;
}
```

### 不同终点的不同费率限额

您可以对不同的操作应用不同的费率限制 :

```ts
// Strict rate limit for auth endpoints
const loginResult = await ctx.ports.rateLimit.hit({
  key: `login:${ctx.ip}`,
  limit: 5,
  windowSec: 300, // 5 attempts per 5 minutes
});

// More relaxed rate limit for API endpoints
const apiResult = await ctx.ports.rateLimit.hit({
  key: `api:user:${userId}`,
  limit: 1000,
  windowSec: 3600, // 1000 requests per hour
});
```

### 使用合同元数据

您可以定义合同的速率限制元数据 :

```ts
const getTodos = api.get("/todos")
  .meta({
    rateLimit: { max: 60, windowSec: 60, scope: "user" },
  });
```

内置 `createRateLimitHooks(...)` 帮助读取此元数据并应用 限制通过 `ctx.ports.rateLimit`。如果您的应用程序需要自定义行为,请保留 并直接调用端口:

```ts
type RateLimitMetadata = {
  rateLimit?: {
    max: number;
    windowSec: number;
    scope?: "global" | "ip" | "user";
  };
};

async function rateLimitFromMeta(ctx: AppContext, meta?: RateLimitMetadata) {
  if (!meta?.rateLimit) return;

  const { max, windowSec, scope = "global" } = meta.rateLimit;
  const actorId =
    ctx.actor?.type === "user" && ctx.actor.id ? ctx.actor.id : undefined;
  const result = await ctx.ports.rateLimit.hit({
    key:
      scope === "user"
        ? `user:${actorId ?? "anonymous"}`
        : `${scope}:${ctx.ip ?? "global"}`,
    limit: max,
    windowSec,
  });

  if (!result.allowed) {
    return {
      status: 429,
      body: {
        code: "TOO_MANY_REQUESTS",
        message: "Too many requests",
      },
    };
  }
}
```

## 费率限制结果

这个 `hit` 方法返回 a `RateLimitResult` 改为:

```ts
interface RateLimitResult {
  allowed: boolean;                 // true if the hit is within the limit
  remaining: number | null;         // requests remaining in the window
  resetAt: Date | null;             // when the window resets
  retryAfterSeconds: number | null; // retry delay when the hit is rejected
}
```

## 执行详情

-   **算法**: 用途 `Ratelimit.fixedWindow()` 默认,或 `Ratelimit.slidingWindow()` 何时 `UPSTASH_ALGORITHM=sliding-window`
-   **后端**: Upstash Redis REST API(无服务器兼容)
-   **按请求配置**: 开关 1 `Ratelimit` 实例数 `(limit, windowSec, algorithm)` 组合到支持动态限制时无需 重建限制符 `hit()` 调用
-   **密钥前缀**: 避免键相撞的可配置前缀

## 开发工具

何时 `@beignet/devtools` 安装在此提供者之前, 费率限制 检查出现在仪表盘的限速监视器下.

提供者的记录 `rateLimit.hit` 带有密钥、限制、窗口、, 配置前缀、算法、允许/锁定结果、剩余计数、重置 时间,重试后值,以及持续时间。 提供者的失败记录为 `rateLimit.hit.failed`。故意故障开放超时记录为 `rateLimit.hit.degraded`,不是一个普通允许的决定.

## 逃逸舱门

提供者提供标准 `rateLimit` 端口加号 `ctx.ports.upstash` 使用原始 Upstash Redis 客户端进行操作 稳定速率限制端口 不建模 :

```ts
// Access the Redis client for advanced operations.
await ctx.ports.upstash.client.get("some:key");
await ctx.ports.upstash.client.set("some:key", "value");

// Use the read-only PING check from readiness and connected preflight.
const health = await ctx.ports.upstash.checkHealth();
```

要获取所贡献端口的正确类型推断, 请扩展您的端口类型 与 `UpstashRateLimitProviderPorts`数字 :

```ts
import type { UpstashRateLimitProviderPorts } from "@beignet/provider-rate-limit-upstash";

type AppPorts = typeof basePorts & UpstashRateLimitProviderPorts;
// Adds rateLimit plus upstash.client and upstash.checkHealth() to AppPorts.
```

使用马厩 `RateLimitPort` 用于正常应用行为。 使用原始数据 客户端只有在 Upstash 特定操作是故意的.

## 失败行为

嵌入式后置提供者在启动时按要求投掷 Upstash 嵌入式 vars 失踪了 网络错误和上层错误的记录和重写不变.

Upstash 的 SDK 无法作出决定时可以返回允许的结果 暂停前 Beignet 默认将这个条件视为错误 : 之后 `UPSTASH_TIMEOUT_MS` (默认) `5000`, (中文(简体) ), `fail-closed` 记录 `rateLimit.hit.failed` 并抛出这样受保护的工作,没有 执行。 设定 `UPSTASH_TIMEOUT_POLICY=fail-open` 只有可用时 比在暴风雨中执法更重要 未打开的超时 返回剩余/重置值未知的允许结果并发射 `rateLimit.hit.degraded`。 。 。 .

## 当地测试

用个假的 `RateLimitPort` 在路线和使用案例测试中。 为了地方发展, 位于 Upstash 开发数据库的点, 或是连接一个应用程序拥有的内存 需要在此提供者之前先限制费率.

## 部署说明

速率限制键是生产行为的一部分. 设定 `UPSTASH_PREFIX` 每个应用程序 因此,预览、中继和制作不共享 自动计数器.

提供商使用 Upstash 的 REST 客户端, 并且没有开始工人或坚持 连接, 因此同一适配器在无服务器和长寿命的 HTTP 中工作 运行时间。 已配置的请求范围超时 并准备PING。 添加 `ctx.ports.upstash.checkHealth()` 给一个应用公司 准备路线; `beignet preflight --connect` 发现相同的检查 自动.

## 测试

提供者包括综合测试。 运行方式:

```bash
bun test
```

## 许可证

麻省理工学院

## 常见问题

### @beignet/provider-rate-limit-upstash 是什么？

Beignet 基于 Upstash 的费率限制提供者 - 使用 Upstash Redis 添加费率限制端口

### 如何安装 @beignet/provider-rate-limit-upstash？

在项目目录运行 npm install @beignet/provider-rate-limit-upstash，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@beignet/core（\>=0\.0\.3 \<1\.0\.0）、@upstash/redis（^1\.0\.0）、@upstash/ratelimit（^2\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @beignet/provider-rate-limit-upstash 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @beignet/provider-rate-limit-upstash 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @beignet/provider-rate-limit-upstash 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22\.12\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @beignet/provider-rate-limit-upstash 可以商用吗？

@beignet/provider-rate-limit-upstash 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @beignet/provider-rate-limit-upstash 的下载量有多少？

根据 npm 官方下载统计，@beignet/provider-rate-limit-upstash 在 2026/10/08 – 2026/11/06 这 30 天内被下载 1,981 次，日均约 66 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @beignet/provider-rate-limit-upstash 还在维护吗？

最新版本 0\.0\.65 发布于 2026/11/08（今天）；至今共发布 65 个版本，其中过去 12 个月发布了 65 个；首次发布于 2026/05/27。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

