when to use a Meteor Method vs normal function? - meteor

I've got, I think, a relatively simple question. I'm wondering in Meteor, especially when I'm defining server-side functions that I want the client to be able to call, when do I use a method vs a normal function? Why can't I just use a global function in my Meteor server code instead of defining a Meteor Method?
thanks!

Functions defined only the server are only accessible to server code (even if defined globally). So for example, if you had a function defined in server/util.js it would not be available to the client.
You could, however, define a function that was global to both the server and the client by placing it outside of the server and client directories, e.g. in lib.
Generally, you would choose to create a method over a function when you want a side effect which should only be produced on the server. Examples:
you need to sign a URL and keep the key only on the server
you need to perform a database operation that can only be done on the server (due to limitations of minimongo)
Important note - method calls from the client are asynchronous (you need to provide a callback function to know the result of the method), so that may also factor into your decision.

Related

Grails 4 Async with Database Operations

My Grails 4.0.10 app needs to call an external service. The call may take up to 3 minutes, so it has to be async'ed. After reading the doco I wrote a non-blocking service method to perform the call using a Promise without too much trouble.
The documentation describes how async outcome can be displayed.
In my case the outcome affects the database. I must create new domain objects, modify existing domain objects and persist the result in the onComplete closure. The doco is rather quiet on how to do this.
These are my assumptions about the onComplete closure. My question is: Are the assumptions valid? Is this the proper way to do it?
No injected stuff is available, neither services nor (for example) log -- things you normally expect in a service
Database logic must be enclosed first within Tenants.withId if multitenancy is used, and then within withTransaction
withTransaction is prefixed with a domain name. However, other domains may freely be manipulated and persisted in the same closure
Domain instances picked up before the async call may be attached to the current session like this instance.attach() and then modified and saved
If logging is needed, create a new log instance

Is using Firebase cloud function library better than direct http call to the same cloud function url

I have an Express server running in firebase cloud function.
Currently, I am calling this cloud function from my client (assume it's a web client) using direct http call to url that was provided to me to access the function.
However, there is another method to call this function which is using thr firebase cloud function library for the client.
My question is : what advantage do I get ( in terms of speed ) if I use the library instead of the direct http call.
My assumption is that the library uses a web socket to accesd the function whereas the direct http call uses http call
I couldn't find anywhere in the documentation saying which one is better
Callable functions invoked using the Firebase SDK were not designed to provide any sort of increase in performance over a normal HTTP request. In fact, on average, you will hardly notice any difference between the two.
It's better to pick the one that meets your needs and preferences rather than thinking about performance. But if you really must choose the one that's faster, you should benchmark your choices yourself to see which one is better for your specific case.
See also: Are Callable Cloud Functions better than HTTP functions?

Meteor: are code inside Meteor.isServer block readable from client?

I am confused as to when you would use the isServer block to put stuff in. obviously, database calls and etc. Does this show up in the client browser?
I would advise against using that instead put your stuff in folders as advised on the unofficial meteor faq
Even if you use if (Meteor.isServer) {...} this block will still be sent down to the client if you don't use the folder structure above i.e putting it in /server. But it will ignore all the code inside it.
On the server side code you would place code you only want to run on the server, i.e Publish functions, and data that would be more sensitive & the user shouldn't have access to.
I think it does get sent down to the client, unless it's in the server folder. In response to one of the comments about sharing global variables, I've been using this pattern. Create the same global variable in client and server folders respectively, and once outside of those folders for any shared code. Initialize the global variable in each place by testing to see if it already exists.
MyVar = typeof MyVar === 'undefined' ? {} : MyVar;
Then, just put methods where you need them. For instance, I'll have a User object with a method that tests to see if the user is authorized. I'll declare the method once on the server global User, and once on the client global User. The methods are different because the server version checks for custom properties on the user object which aren't available on the client. Then, in a Meteor.methods method, which runs on both the client and server, you can invoke the authorization method, and it will call different methods depending on if it's running on the client or server.
I was asking myself the same question today and stumbled upon this package:
https://github.com/mquandalle/meteor-minifiers
It seems like Meteor does not remove the Meteor.isServer Blocks by default.
See this discussion:
https://groups.google.com/forum/#!topic/meteor-talk/iHat47f6iGE
I haven't used it as of now, but it looks promising.
If you do not want to use an extra package, I'd recommend to use the client and server folders. Only the files in the client folder are sent to the client.

Where should Meteor.methods() be defined?

http://docs.meteor.com/#meteor_methods
I have tried it in publish.js in my server folder.
I am successfully calling Meteor.apply and attempting the server call from the client. I always get an undefined response.
Calling Meteor.methods on the server is correct. That will define remote methods that run in the privileged environment and return results to the client. To return a normal result, just call return from your method function with some JSON value. To signal an error, throw a Meteor.Error.
On the client, Meteor.apply always returns undefined, because the method call is asynchronous. If you want the return value of the method, the last argument to apply should be a callback, which will be passed two arguments: error and result, in the typical async callback style.
Is your server code actually getting called? You can check that by updating the DB in the method and seeing if the client's cache gets the new data, or calling console.log from inside the method body and looking at the output of the "meteor" process in your terminal.
There are several places I can define my Meteor.methods() (with pro's and con's):
On the server only - when the client calls the method, it'll have to wait for the server to respond before anything changes on the client-side
On the server, and uses a stub on the client - when the client calls the method, it will execute the stub method on the client-side, which can quickly return a (predicted) response. When the server comes back with the 'actual' response, it will replace the response generated by the stub and update other elements according.
The same method on both client and server - commonly used for methods dealing with collections, where the method is actually a stub on the client-side, but this stub is the same as the server-side function, and uses the client's cached collections instead of the server's. So it will still appear to update instantly, like the stub, but I guess it's a bit more accurate in its guessing.
I've uploaded a short example here, should you need a working example of this: https://gist.github.com/2387816
I hope some will find use of this addition, and this doesn't cloud the issue that methods are primarily intended to run on the server as debergalis has explained.
Using Meteor.methods() on the client is useful too. (look for "stub" in the Meteor.call() section too...)
This allows the client to (synchronously) simulate the expected effect of the server call.
As mentioned in the docs:
You use methods all the time, because the database mutators (insert,
update, remove) are implemented as methods. (...)
A separate section explaining use of stubs on the client might ease the understanding of methods calls on the server.

node.js asynchronous initialization issue

I am creating a node.js module which communicates with a program through XML-RPC. The API for this program changed recently after a certain version. For this reason, when a client is created (createClient) I want to ask the program its version (through XML-RPC) and base my API definitions on that.
The problem with this is that, because I do the above asynchronously, there exists a possibility that the work has not finished before the client is actually used. In other words:
var client = program.createClient();
client.doSomething();
doSomething() will fail because the API definitions have not been set, I imagine because HTTP XML-RPC response has not returned from the program.
What are some ways to remedy this? I want to be able to have a variable named client and work with that, as later I will be calling methods on it to get information (which will be returned via a callback).
Set it up this way:
program.createClient(function (client) {
client.doSomething()
})
Any time there is IO, it must be async. Another approach to this would be with a promise/future/coroutine type thing, but imo, just learning to love the callback is best :)

Resources