Methods vs. ValidatedMethos

Is there a difference between using ValidatedMethod or using ‘normal’ methods with check() and a SimpleSchema for the check()? Would like to hear your option to that…

ValidatedMethod

insertArticle = new ValidatedMethod({
		name: 'article.insert',
		validate: new SimpleSchema({
			title: 		{ type: String }, 
			language: 	{ type: String }
	}).validator(),
	run( document ) {
		if (!this.userId) {
			throw new Meteor.Error('Articles.methods.insertArticle.notLoggedIn', 'Must be logged in to create new article.');
		}
		Articles.insert( document );
	}
});

Method

Meteor.methods({
	'article.insert': function(data) {
	if (!Meteor.userId()) {
		throw new Meteor.Error('Articles.methods.insertArticle.notLoggedIn', 'Must be logged in to create new article.');
	}
	check(data, new SimpleSchema({
			title: 	 	{ type: String },
			language: 	{ type: String }
		})
	);
	Article.insert( data );
});

The ValidatedMethod package was created to help deal with a lot of the Meteor Method boilerplate that has become necessary over the years. The Guide explains this in detail in the Advanced Method boilerplate section. As to why the Guide (and ValidatedMethod) use SimpleSchema instead of check, I’ll quote @sashko (source):

  1. Avoid having two different ways to check types
  2. Reuse db schema in method args
  3. This throws formatted validation errors, which can be inspected on the client - check throws opaque errors with no info.

One of the more valuable features that isn’t represented in your not quite equivalent Method is that the ValidatedMethod will not make a server side call if the validation fails because the validation is actually performed prior to calling the method under the hood. Input error info gets back to the user instantly and the server’s time is not wasted.

The mixin feature is nice too. For example, simply including the tunifight:loggedin-mixin will make sure Meteor.userId is always checked. Below is your example rewritten a touch to take advantage of that, the simple-schema-mixin, and schema reuse which is cool for making sure your arguments match your schema’s expectations without duplicating code. It makes the assumption that you have defined a schema that includes ‘title’ and ‘article’ fields and used attachSchema to connect it to the Articles collection.

insertArticle = new ValidatedMethod({
  name: 'article.insert',
  mixins: [LoggedInMixin, simpleSchemaMixin],
  schema: Articles.simpleSchema().pick(['title', 'language']),
  run({ title, language }) {
    Articles.insert({ title, language });
}
});
1 Like

Wow, that looks very interesting to me. Could you please show me how to define the schema? An example would it make easier for me to understand.

For schema you can use SimpleSchema : https://github.com/aldeed/meteor-simple-schema

I meant how to define a simpleSchema to reuse it whenever I need it. In the example code of rlivingston schema: Articles.simpleSchema().pick(['title', 'language'])

It’s the feature of SimpleSchema. https://github.com/aldeed/meteor-simple-schema#extracting-simpleschemas

That would look something like

const articleSchema = new SimpleSchema({
  _id: {
    type: String,
    regEx: SimpleSchema.RegEx.Id,
  },
  title: {
    type: String,
  },
  language: {
    type: String,
    allowedValues: [
      'en',
      'sp',
      'de',
      ...
    ],
  },
  ...
});

Articles.attachSchema(articleSchema);

See the README at rlivingston:simple-schema-mixin for a more extensive example of schema reuse techniques paired with ValidatedMethod or aldeed:simple-schema for more info on defining schemas.

1 Like

I’ve been using Validated Methods in production, without SimpleSchema. Works just fine (I use check instead). It seemed overkill to me to include SimpleSchema in my project just to validate object properties.

2 Likes