How to organize and structure Meteor Methods

/server/methods.js
Meteor.methods({
  createReceipt: function (values) {
  },

  exportReceipts: function() {
  },

  validateUsername: function(username) {
  }
});

What happens in a large app where I can have several different methods: Do I just plop them all into this file?

Can I spread out these methods into multiple files?

It looks like Meteor.methods() accepts a javascript object of different functions, but I’m not sure if I call it from different places if it appends the newer functions or just replaces them.

Any thoughts?

3 Likes

I have one method per file. I name the file the same as the method. And at the top of the method, I write what the method is for, what parameters it accepts. I have no idea if this is a best practice, but here is an example:

////////////////////////////////////
// Name: saveLicenseData
// Purpose: To save the users license data
// Parameters: Accepts a single object containing the user's license data
//             (1) licenseData.licenseType - String - required: The users license type, e.g., CPA, CFE
//             (2) licenseData.licenseDate - Moment Object - required: The users license type, e.g., CPA, CFE
//             (3) licenseData.licenseState - String Required -  The users state of licensure, may be "NA"
//             (4) licenseData.licenseNumber - String - optional: The users license number
///////////////////////////////////
Meteor.methods({
  saveLicenseData: function(licenseData) {
   //Do someStuff
   return someStuff;
  }
});

I should probably document what the method returns as well… but I don’t

You can place as many as you’d like and it will just register those functions with the system. Some people will spread them wherever they need them, which can be confusing. I prefer to add them to server/methods and then place a file for each ‘domain’ in that folder, for example server/methods/posts.js.

1 Like

Thanks for the info guys, I’ll split them out since they append the functions.

1 Like

I use one file with methods per package.

1 Like

you should give JSDoc a shot http://usejsdoc.org/ it gives you a structured way to document modules and methods, and has lots of tooling around it for generating documentation. also most IDEs recognize it and use it for things like letting you know when you break your own rules or displaying the method/module’s description when you search for or hover over it

1 Like

You can have an arbitrary number of Meteor.methods calls in your code. When my project grew I organized functionality through a simple filesystem structure to keep methods with the code where they belong (simply for my own sanity).

Recently I also started to namespace my methods by adopting a dot notation for the method names

// Comment Methods
Meteor.methods({
 'Comment.add': function(comment) {
 },
 'Comment.delete': function(id) {
 },
 ...
})
2 Likes

Now that’s a good idea. I’ll also namespace these methods that way. :thumbsup:

Is there a way to pop up the method’s JSDoc description when I start typing Meteor.call("methodName", ...? I’m using sublime and tried a couple of packages, but none of them worked.

that’s a great question, I’ve only ever seen it work for plain javascript functions. that would be a great IDE plugin to allow JSDoc functionality for Meteor methods too, I use it in all my JS projects

If you’re starting to build a mid to large scale app, I’d recommend using MDG’s Validated Method pattern: https://atmospherejs.com/mdg/validated-method

It basically gives you regular functions from your Meteor methods:

const myMethod = new ValidatedMethod({ /* definitions */ });
myMethod.call('args');

which makes it possible to attach them to namespaces and make calls like:

Namespace.domain.method.call('args');

rather than sprinkle Meteor.call() with brittle string method names all over:

Meteor.call('domain/method', 'args');

In Meteor 1.3, you don’t even have to make the namespaces global, but will probably be able to use ES6 to import them wherever as well.

6 Likes

I split my app into modules like this:

app\
    	addPost\
    	signUp\
    		server\
    			signUp-server.coffee
    		signUp.coffee
    		signUp.jade
    		signUp.styl
    	someOtherModule\

And put all server code for signUp module including methods into signUp-server.coffee file.

1 Like

Actually, that’s an antipattern. I learnt it just now. You should split client and server code bw client and server folders, where possible.

app\
    	addPost\
    	signUp\
    		server\
    			signUp-server.coffee
    		client\
    			signUp.coffee
    			signUp.jade
    			signUp.styl
    		shared-code-eg-flowRouter.coffee
    	someOtherModule\

That way, when you make changes to client-only file - only client has to be refreshed.
When you make changes to server file - only server is restarted, client keeps its current state.
When you make changes to a shared file - whole app needs to be restarted.