@beignet/provider-rate-limit-upstash

中文文档
0.0.65发布于 2026/11/08MITTypeScriptES Module近 30 天下载 1981

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

中文使用文档
文档目录19 节
  1. 特征
  2. 安装
  3. 配置
  4. 选择一个算法
  5. 获取 Upstash 证书
  6. 设置
  7. 直接适配器
  8. 直接使用
  9. 不同终点的不同费率限额
  10. 使用合同元数据
  11. 费率限制结果
  12. 执行详情
  13. 开发工具
  14. 逃逸舱门
  15. 失败行为
  16. 当地测试
  17. 部署说明
  18. 测试
  19. 许可证

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

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

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

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

提供者安装 ctx.ports.rateLimit 使用 升起雷迪丝 财务报告和审定财务报表 @ upstash/ 速率限制。 。 。 .

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

特征

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

安装

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

配置

设定这些环境变量 :

变量需求说明示例
UPSTASH_REDIS_REST_URL对您的 Upstash Redis 更新 URLhttps://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. 报名到 上图
  2. 创建一个新的 Redis 数据库
  3. 导航到数据库细节页面
  4. 从“ REST API” 部分复制 REST URL 和 REST 令牌

设置

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

bun beignet provider add rate-limit-upstash
bun install

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

手工提供者注册,导入 createUpstashRateLimitProvider 从此包中添加 createUpstashRateLimitProvider() 给您的提供者 列表中选择一个选项。 跟着 费率限制指南 页: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 衍生值 :

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 时 客户端 :

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 保留 直接接线的提供者事件.

直接使用

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

// 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;
}

不同终点的不同费率限额

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

// 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
});

使用合同元数据

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

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

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

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 改为:

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 客户端进行操作 稳定速率限制端口 不建模 :

// 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数字 :

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 发现相同的检查 自动.

测试

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

bun test

许可证

麻省理工学院

版本与发布记录

@beignet/provider-rate-limit-upstash 共发布 65 个版本,首次发布于 2026/05/27;过去 12 个月发布了 65 个版本。

版本发布日期距今
0.0.65latest2026/11/08今天
0.0.642026/11/034 天前
0.0.632026/11/026 天前
0.0.622026/11/017 天前
0.0.612026/11/017 天前
0.0.602026/11/017 天前

关于 @beignet/provider-rate-limit-upstash 的常见问题

@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 和提交记录判断。