mcpField
M
meteor-methods

meteor-methods

github.com/meteor开发10293 次安装5 天前更新
代码仓库

关于 meteor-methods

用于实现 Meteor methods 的技能,即客户端调用的服务器端数据变更接口。内容涵盖参数验证、乐观 UI 存根、速率限制和错误处理,面向 Meteor 开发者。

主要功能

  1. 01异步服务器端方法
  2. 02使用 check() 验证参数
  3. 03乐观 UI 客户端存根
  4. 04DDP 方法速率限制
  5. 05客户端可见的错误处理

适用场景

  1. 01构建经过验证的服务器端变更
  2. 02显示乐观的本地更新
  3. 03限制敏感方法的调用频率
  4. 04处理方法和传输错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/meteor/agent-skills --skill meteor-methods

安装后在 Claude Code 中输入/meteor-methods确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
check-and-validate.md
eval-cases.md
rate-limiting.md

详细介绍

Meteor 方法

方法是 Meteor 用于从客户端发起服务端数据修改的基本机制。 在 Meteor 3 中,服务端方法是异步的。延迟补偿仍通过客户端存根实现。

决策流程

  1. 这段代码是否会修改服务端数据?使用方法。
  2. 客户端是否需要在服务端响应之前读取结果?编写一个同名的客户端存根;它会修改本地 Minimongo 集合,如果服务端结果不一致,这些更改就会回滚。
  3. 方法是否接受不可信的输入?使用 check() 验证每个参数。否则,Agent 应拒绝编写该方法。
  4. 方法是否对速率敏感?添加 DDPRateLimiter.addRule。

脚手架

import { Meteor } from "meteor/meteor";
import { check, Match } from "meteor/check";

Meteor.methods({
  async addItem(payload) {
    check(payload, {
      title: String,
      qty: Match.Integer,
    });
    if (!this.userId) {
      throw new Meteor.Error("not-authorized");
    }
    const _id = await Items.insertAsync({
      ...payload,
      ownerId: this.userId,
      createdAt: new Date(),
    });
    return _id;
  },
});

从客户端调用

try {
  const id = await Meteor.callAsync("addItem", { title: "Hi", qty: 1 });
  setLocalId(id);
} catch (err) {
  if (err && typeof err === "object" && "error" in err) {
    console.error(err.error, err.reason, err.details);
  } else {
    console.error("local or transport failure", err);
  }
}

乐观 UI

在客户端定义同一个方法。客户端存根会立即对本地 Minimongo 执行操作;服务端的权威结果会回滚任何不一致之处。

// client/methods.js
import { Meteor } from "meteor/meteor";
import { Random } from "meteor/random";
Meteor.methods({
  addItem(payload) {
    Items.insert({
      ...payload,
      _id: Random.id(),
      ownerId: Meteor.userId(),
      createdAt: new Date(),
    });
  },
});

如果只需要同步的 Minimongo 操作,同步存根最简单。callAsync 也支持异步存根;当同一个方法定义在客户端和服务端运行,并使用 *Async 集合调用时,异步存根很有用。 异步存根可以等待基于微任务的本地操作,但不能等待 fetch、计时器、IndexedDB、工作线程或其他浏览器宏任务 API。应在存根之外执行外部 I/O。

速率限制

import { DDPRateLimiter } from "meteor/ddp-rate-limiter";

DDPRateLimiter.addRule(
  {
    type: "method",
    name: "addItem",
    userId: (userId) => Boolean(userId),
  },
  5,        // operations
  10000,    // per 10s
);

Meteor 3.5+ 允许为数据库决策使用异步匹配器。在 Meteor 3.0 到 3.4 中,匹配器必须保持同步;应使用固定规则、预先计算的同步状态,或升级版本,而不是在匹配器中等待 Mongo。

Meteor 会在传入连接的消息队列中依次等待异步匹配器。只投影所需字段,并确保查询足够快。如果匹配器 Promise 被拒绝,该次调用就会报错;请明确测试这种情况。

有关规则对象的架构,以及按连接与按用户设置键的说明,请参阅 references/rate-limiting.md。

错误处理

对于有意让客户端可见的失败,抛出 Meteor.Error(code, reason, details?)。普通 Error 会在服务端记录日志,并在发送给客户端前进行脱敏,变为 Meteor.Error(500, "Internal server error");其原始消息和堆栈不会暴露。Meteor.Error 包含其代码、原因和详情。不要假设每个 callAsync 拒绝都会是这种格式:回调误用、传输失败和本地存根异常都可能产生原生错误或其他错误。读取 Meteor 专属字段之前,先缩小捕获值的类型范围。

反模式

  • 未对每个参数使用 check() 的方法。应在代码审查中拒绝此类方法。
  • 将同一个方法用于已认证和未认证的调用。应拆分为两个方法。
  • 在客户端存根中等待 fetch 或计时器等浏览器宏任务 API。异步存根是有效的,但这些 API 会让无关代码在乐观模拟完成前运行。
  • 在异步方法体内调用 Meteor.user()。请使用 this.userId。

另请参阅

  • references/check-and-validate.md
  • references/rate-limiting.md
  • references/eval-cases.md

评论

支持 Markdown