Method definition

How do you define methods (server)

Meteor.methods({
  'method.one': () => {
    console.log(this.userId); // undefined
  },
  'method.two': function() {
    console.log(this.userId); // current logged in user id
  },
  methodThree() {
    console.log(this.userId); // current logged in user id
  },
});

method.one looks cool but there is some limitations :joy:

I usually use one of:

methodThree() {
  //...
},
`method.four'() {
  // ...
},
async methodFive() {
  // ...
},
async 'method.six'() {
  // ...
}

I don’t use fat arrows for methods because of the loss of this context (but they work fine otherwise).

9 Likes

I define them like this:

Meteor.methods({
    example() {
        //...
    },
    // OR
    'example.method'() {
        //...
    },
});

Unless i’m writing enterprise mode Meteor which looks like this:

export const createPage = new ValidatedMethod({
    name: 'pages.create',
    allow: PermissionsMixin.LoggedIn,
    validate: pageSchema.pick('projectId', 'name').validator({ clean: true }),
    run(page) {
        ProjectSecurity.isEditableBy(page.projectId, this.userId);
        return PageService.create(page);
    },
});
2 Likes

To be honest, I don’t really understand your enterprise part. Haha.

What I love and at the same time hate about JS in general is that you can do the same thing a thousand ways. Writing methods is just an example.

In our case, we even ended up extending the validated method class:

methods.push(
  new SecuredMethod({
    name: 'store.get.user.business',
    mixins: [access],
    validators,
    run(params) {}
  })
);

And to ensure that everyone in our team is using the same way of defining a method, we ended up creating a custom eslint rule dedicated for it :slight_smile:

1 Like

Yeah we actually use a custom subclass of ValidatedMethod as well with some extra security, default mixins and using promises!

@minhna, that’s how you know it’s extra Enterprisey :wink:

If you’re curious the whole validatedMethod thing is in the guide: https://guide.meteor.com/methods.html#validated-method

1 Like

I’m just curious, can you share how the definition of SecureMethod looks like? Thanks!

@coagmano was the original proponent of this idea

https://forums.meteor.com/search?context=topic&context_id=48037&q=SecuredMethod&skip_context=true

1 Like

SecuredMethod comes from here: https://github.com/didericis/permissions-mixin/#adding-a-securedmethod

I’ve modified slightly for our own preferences:

import { PermissionsMixin } from 'meteor/didericis:permissions-mixin';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import pify from 'pify';

export const SecuredMethod = class SecuredMethod extends ValidatedMethod {
    constructor(methodDefinition) {
        super({
            ...methodDefinition,
            mixins: [...methodDefinition.mixins, PermissionsMixin],
        });
    }
    /**
     *
     * @param {...any} args - the arguments passed to the method
     * @returns {undefined|Promise} - If a callback was not supplied, this returns a Promise
     */
    call(...args) {
       const maybeCb = args[args.length -1];
        if (typeof maybeCb === 'function') {
            return super.call(...args);
        }
        return this.callPromise(...args);
    }

    callPromise = pify(super.call.bind(this));
};

It merges the method’s definition with PermissionsMixin and then passes it on.
It also automates promisifying calls if no callback was supplied.

All the heavy lifting is done by reusable permissions objects designed for use with PermissionsMixin.
Like the builtin PermissionsMixin.LoggedIn, we have others for other groups and such

Again, keeping each concern separated out for loose coupling, re-usability and testability.

Our architecture took a lot of inspiration from meteor-tuts

1 Like