Downsides of calling Meteor methods on the server

Hi all,

read several docs and posts stating that a server side Meteor method call is possible but not recommended.

Besides from maybe unnecessarily enabling method calls to the client, and maybe redundant parameter and auth checks, are there other significant (performance) downsides?

Hello Bratelefant :elephant: :fire: :fire_engine:

I think thatā€™s basically it, at least for me.

It has some / considerable overhead call-wise which isnā€™t that important if you call methods to trigger important actions one by one, but could get into trouble if you for example would create smaller methods to update / fetch some informationfor something and then would use that in a loop more than a handful of times.

(And these things can happen by accident eg. if you bury code to call another method in another function / method. These things can sneak up on ya! :smiley: )

This could of course become a problem especially with nested calls, which then could add up to a lot of overhead. Itā€™s just simpler and more efficient to just call it what it is, a function, which has much less / almost neglible overhead.

Think about a situation like this:

Client call: fetchProductsListFromServer()
    Server: Find products(...) (maybe returns 20 products)
        forEach product:
            call getAdditionalInfoForProduct()
            call getRelatedProducts()
                getRelatedProducts:
                    call getProducts(relatedTo: xyz)
                    call getAdditionalInfoForProduct(relatedProduct)

So now you might have 20 products times 10 related products with additional helper methods ā†’ 200 things to call. Each Meteor.Method - call would add considerable overhead.

This is just an example of course, but could lead to notice-able higher load & longer reaction times.

Also, from a ā€œcode designā€ standpoint: Iā€™d say that a Method IMPLIES it being called from outside somewhere. If you donā€™t plan to call it from the outside, why make it a method in the first place? Itā€™s kind of misleading to others reading the code, so to speak.

Why would you like to use methods more often than strictly required?

Best

2 Likes

Calling Meteor methods from the server will stop working when Meteor switches from Fibers to async/await, wich will have to happen next year (when NodeJS support for Fiber stops).

Hi @janmp , this is definitely interesting to me - but I seem to haved missed the boat on this.

Where can I read more about this, probably on the github issue? I only know that it is a bigger project and has been worked on for some time.

Can you give me a hint on where to read up on the current status?

Because I didnā€™t know that the backwards compatibility would have to be broken in major ways like this.

Thanks and best

Daniel

Hey Daniel, I have some methods in my noob starter project, which I could also use on the server side, so somehow I just kept using meteor methods for not repeating myself / factoring.

Now since this whole project got more complex, I decided to just do what you advised, ie defining methods iff theyā€˜ll be accessed by a client. The rest will be JS functions on the server.

Yeah, thatā€™s the exception to the rule I think. If itā€™s because you have a number of similar methods anyhow, I would keep that pattern if itā€™s not too many ā€œnon-necessary-method methodsā€, eg. to keep an API consisten.

And for code reuse / simplicity itā€™s not a big deal to call a method from the server itself, I just wanted to differentiate between when Iā€™d ā€œreach forā€ methods by default vs functions.

But of course now that @janmp gave us advance warning, maybe we need to keep an eye on these changes as well - though in the past meteor always gave enough time to migrate and generally enabled humane upgrade paths wherever possible.

I guess Iā€˜ll try to follow the DRY principle by doing like so:

export const doServerStuff = (param) => {
   if (Meteor.isServer){
       ā€¦
    }
}

Meteor.methods({
    'doSomething'(param){
        check(param,String); // do some validation
        checkPolicies(ā€¦); // User allowed to call that method
        doServerStuff(param);
    }
})
1 Like

Why would you need to call a method on the server side when you have access already to everything a method can do that is abstracted from the client side? The whole point of methods is to pass data to the client from the server. Thatā€™s why you donā€™t need to call methods on the server, just call a functionā€¦ you donā€™t need to send anything over the wire itā€™s already on the server.

2 Likes

Yeah thatā€™s the way to do it in case you do something which is called a lot.

Thereā€™s some additional things to considerā€¦

Theres eg GitHub - meteor/validated-method: Meteor methods with better scoping, argument checking, and good defaults. which provides, besides other things a nice framework for adding additional ā€œlayersā€ / plugins to the methods. Validation via the simple-schema - plugin are a staple for example:

ā†’ for methods which arenā€™t called a lot (eg. in big loops) itā€™s fine to call them from the server too, thatā€™s fine, we do it all the time as well. Just be aware in case you nest a lot of it that it might slow things down eventually. Itā€™s overhead.

There are even more things to considerā€¦ if you accept calls from the server - how can you be sure itā€™s a legal call? You donā€™t then have a validated user for example, but if you need to be sure that the user is either validated or from the server you have to find a system to use to make sure that no unvalidated user can call the method from the outsideā€¦

Thatā€™s true; you can check whether a method is called from the server by checking this.connection is undefined. But right there things become awkward; I have methods that are needed on the server side in some db migration steps, and also client-sided by authed users / users with a certain role.

Rather than doing this if (!Roles.userIsInRole(Meteor.user(), ā€žopā€œ) && this.connection !== undefined) { throw new Meteor.Error('Not allowed')} in the method to be able to call this before server startup for db migrations itā€™s much more consistent to have a server side regular JS function, that can be used by the migration step and, after checking policies, by the method.

Oh man @janmp , you donā€™t really want me to finally learn how async/await works now after all these years? :smiley:

Nah, use Coffeescript. That will take care of the async for you, so you just have to deal with the awaits. :stuck_out_tongue_winking_eye:

I am curious to learn more about this. How are these two interrelated?

Thereā€™s a lengthy discussion about fibers in this thread: Meteor Roadmap questions

3 Likes