Run Server Method as different Meteor.user() for a REST API route

Hi all,

I’m struggling right now to get the following to work:

I have a Picker HTTP route. Once that route is requested (using a bearer token associated with a Meteor.user), a server method should be run in the scope of that user (and finally send a response).

Of course, if I run console.log(Meteor.user()) I get undefined. Is it possible to do something like this:

Picker.route("/api/v1/myrequest", function (params, req, res, next) {

  Meteor.bindEnvironment(function () {
    Meteor.user = () => req.meteorUser; // meteorUser is added by middleware based on bearerToken
    Meteor.userId = () => req.meteorUser._id;
    const result = Meteor.call("mymethod");
    res.end(result);
  })();
});

You can use _CurrentMethodInvocation - which is what Accounts.userId (and the Meteor equivalent) uses.

Whether you should do this or not is a separate question (hint - you probably shouldn’t).

res.end(DDP._CurrentMethodInvocation.withValue(
  new DDPCommon.MethodInvocation({
     userId: req.meteorUser._id,
  }),
  () => Meteor.call("mymethod");
}))
1 Like

Thanks for the immediate help. It works as expected, although I’m wondering what possible downsides you have in mind

The big downside is it works on the assumption that this will always be how meteor tracks the user ID, and also that there is no code in any of your methods (or in packages called by your methods) that make other assumptions about what will exist in the DDPCommon.MethodInvocation when it is provided.

So long as you test thoroughly and are aware of this, there’s nothing specifically wrong with it,

My larger point is that you probably shouldn’t be calling a meteor method from the server at all - extract that method to a function, import it into your API and call it directly. Then, instead of relying on Meteor.userId() - just pass in the userId directly. If you still require the method be exposed, you can then do this:

Meteor.methods({mymethod() { 
 myExtractedMethod(Meteor.userId())
})
1 Like