web-dev-qa-db-ja.com

Meteor.methodsを使用してスタブを利用する場合

Meteorを使用して、UIの即時更新を維持しながら、サーバー側のMeteor.methods()をいつ使用するかを理解しようとしています。

Andrew Scalaの 入門チュートリアル から、彼は、データベースドキュメントを更新および変更する場合は、Meteor.methods()を使用する必要があると主張しています。

データの変更や更新などの危険な処理を実行するサーバー上のすべての関数を定義し、クライアントにそれらの関数を呼び出して、通常の関数のように戻り値を取得させるという考え方です。クライアントは実装を確認したり、データを個人的に変更したりすることはありません。サーバーがすべての作業を行います。

そして、このアドバイスに従って、これをコードに実装しました。

サーバ側:

_Meteor.methods({

  addMovie: function(data) {
    var movie = Movies.insert({name: data});
    return movie;
  },

  ...
_

クライアント側:

_Template.movies.events = ({

  'click #add-movie': function(e) {

    var name = document.getElementById('movie-name').value;
    Meteor.call('addMovie', name);

    return false;

  }, 

  ...
_

これは機能しますが、遅いです。クライアント側でMovies.insert()を呼び出した場合のように、UIはすぐには更新されません。 docs は、問題を修正するために、クライアント側でスタブを作成できることを示しています。

クライアントでメソッドを呼び出すと、同じ名前のサーバーメソッドに関連付けられたスタブ関数が定義されます。必要がなければ、メソッドのスタブを定義する必要はありません。その場合、メソッド呼び出しは他のシステムのリモートプロシージャコールと同じであり、サーバーからの結果を待つ必要があります。

しかし、これらのスタブはどのように見えるべきですか?基本的にサーバー側の方法と同じように見えるべきですか?もしそうなら、ポイントは何ですか? Meteor.methods()の使用法と目的、スタブのポイント/使用法、およびそれらの実装について、より包括的な説明を探しています。

編集:David Greenspanは、 meteor-talkでのMeteor.methods()とスタブの使用を明確にするのに役立ちました

33
bento

ここに別の例があります。

ビンゴゲームを書いているときにボタンをクリックして「house!」を呼び出すとします。クリックイベントでは、メソッドを呼び出すことができます。

Method.call("callHouse");

これにより、サーバーメソッドが呼び出されます。

// on the server
Meteor.methods({
  callHouse: function () {
    if (currentGame.isInProgress) {
      currentGame.winner = this.userId;
      currentGame.end();
    }
  }
});

あなたが最初に「家」を呼び出す場合、メソッドはあなたを勝者としてマークします。ただし、メソッドが非常に遅く、クライアントアプリが待機しているとしましょう。サーバーがあなたを確認することを99%確信しています。勝者-待機せずにユーザーの画面を更新したいだけです。この場合、クライアント側のスタブを実装します。

// on the client
Meteor.methods({
  callHouse: function () {
    currentGame.winner = Meteor.userId();
    // add any other side-effects you expect to occur here
  }
});

サーバーの結果が返されるときに、返されるデータがスタブに設定したものと異なる場合、サーバーはそれを修正し、それに応じて画面を更新します。

19
Lloyd

要するに :

サーバー上で実際の作業を行うサーバーにプッシュされたファイルにいくつかのメソッド(Meteor.methods)を定義し、クライアントにプッシュされたファイルにいくつかのメソッド(Meteor.methods)を定義して、クライアントで「インスタント」動作を取得します(サーバーが結果の変更をクライアントにプッシュバックするまで、ロードインジケーターなど)

これがDavidの元の投稿です:

ベンさん、こんにちは、

原則として、メソッドはクライアントとサーバーで完全に異なるアクションを実行できます。たとえば、クライアントに読み込みインジケーターを表示したり、サーバー上のリモートAPIと通信したりできます。クライアントでのMeteor.methodsの呼び出しはクライアントの動作を定義し、サーバーでのMeteor.methodsの呼び出しはサーバーの動作を定義します。

データベースを操作するメソッドの場合、多くの場合、同じ実装で両方を実行できます。クライアントバージョンはクライアント側データベース(サブスクライブされたドキュメントのブラウザ側「キャッシュ」)に影響し、サーバー側バージョンは実際のデータベースに影響します。クライアントが応答を返すと、サーバー側の変更の結果に「スナップ」します。クライアント側のデータベースの変更は破棄されます(または、考え方によっては元に戻されます)。クライアント側のメソッドが他のメソッドを呼び出す場合、これらの2次呼び出しはnotサーバーにリモート接続されます。サーバー側のバージョンは、サーバー上で同じメソッドを呼び出すか、呼び出さないかのどちらかです。

したがって、提供するクライアント側のメソッドimplは単なる「シミュレーション」であり、正確である必要はありません(正確である必要はありません)。サーバーの実装と同じであるため、通常はシミュレーションの実装を無料で入手できることを願っています。

これはあなたの質問に答えますか?

-ダビデ

12
jay

/collectionsのようにクライアント/サーバーで共有されるファイルにメソッドを定義すると、両方にアクセスでき、自動的にスタブされませんか?

そう:

/collections/houses.js

Meteor.methods({
  callHouse: function () {
    if (currentGame.isInProgress) {
      currentGame.winner = this.userId;
      currentGame.end();
    }
  }
});

これは、クライアントとサーバーの両方で利用できます。合格しなかった場合、サーバーはクライアントの更新を自動的に拒否/元に戻します。

3
Daniel Fischer

ダニエルが言ったように、クライアントまたはサーバーのディレクトリになく、両側で利用できるファイルにメソッドを定義できます。 isSimulationブール値を使用して追加のチェックを行うこともできます。たとえば、次のようになります。

Meteor.methods({
  addMovie: function (movieData) {
    if (!this.isSimulation) {
      check(movieData, someAdditionaCheckinFunc);
    }
    Movies.insert(movieData);
  }
})

したがって、条件分岐のコードはサーバー上でのみ実行されます。

3