mcpField
M
meteor-methods

meteor-methods

github.com/meteor開発10293 回インストール5 日前に更新
リポジトリ

meteor-methods について

クライアントから呼び出すサーバー側の変更処理、Meteor methods の実装を支援するスキルです。引数検証、楽観的 UI のスタブ、レート制限、エラー処理を扱います。

主な機能

  1. 01サーバー側の非同期メソッド
  2. 02check() による引数検証
  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() で検証します。そうでない場合、エージェントはメソッドの記述を拒否する必要があります。
  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() を行わないメソッド。コードレビューで却下してください。
  • 認証済みの呼び出しと未認証の呼び出しに同じメソッドを再利用すること。2 つのメソッドに分割してください。
  • クライアントスタブ内で fetch やタイマーなどのブラウザーのマクロタスク API を待機すること。非同期スタブは有効ですが、こうした API を使うと、楽観的シミュレーションが完了する前に無関係なコードが実行されます。
  • 非同期メソッドの本体で Meteor.user() を呼び出すこと。代わりに this.userId を使ってください。

関連項目

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

コメント