When to use Meteor.methods and utilizing stubs

依然范特西╮ 提交于 2019-11-28 15:59:37

here's another example.

say you're writing a bingo game and you click the button to call "house!".. in the click event you might call a Method, e.g.

Method.call("callHouse");

this will invoke the server method:

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

if you are the first to call "house", the method will mark you as the winner.. however, let's pretend the method is extremely slow and your client app is waiting.. you're 99% sure the server will confirm you are the winner - you just want to update the user's screen without the wait.. in this case implement a client-side stub:

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

when the server result returns, if the data returned is different to what you set in the stub, it will correct it and refresh the screen accordingly.

In short :

Define some methods (Meteor.methods) in the files pushed to the sever that will do actual work on the server, define some methods (Meteor.methods) in the files pushed to the client to get an 'instant' behavior on the client (such as a loading indicator) until the server pushes the resulting changes back to the client

Here's David's original post :

Hi Ben,

In principle, a method can perform completely different actions on the client and server, for example showing a loading indicator on the client and talking to a remote API on the server. Calls to Meteor.methods on the client define the client behavior, and calls to Meteor.methods on the server define the server behavior.

For methods that operate on the database, often the same implementation will do for both. The client version affects the client-side database (the browser-side "cache" of documents subscribed to) and the server-side version affects the real database. When the client hears back, it "snaps" to the result of the server-side mutations; the client-side database mutations are discarded (or undone, depending on how you think about it). If a client-side method calls other methods, these secondary calls are not remoted to the server. The server-side version will either call the same methods on the server, or not, as it sees fit.

So any client-side method impl you provide is just a "simulation" and doesn't have to be accurate (it may not be able to be). The hope is that you typically get the simulation impl for free because it's the same as the server impl!

Does this answer your question?

-- David

If you define a method on a file shared by client/server like /collections wouldn't it be accessible to both and automatically stub?

So:

/collections/houses.js

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

This will be available to both the client and server. If it doesn't pass, the server will automatically reject the client update/revert it.

As said Daniel you can define a method on a file which not in client or server directories and available on both sides. You can also use isSimulation boolean value to make additional checking. For example it may looks something like this:

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

Thus code in the conditional branch will be executed on server only.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!