I also roll my own with a boilerplate. Here’s an example from the React-ive Meteor example app. I personally don’t like using auto-form, simple-schema, etc… because I don’t want to deal with breaking changes, rigid API’s, etc…
I like this setup because:
- easy to share with other servers (via DDP)
- easy to reason about security on a per method basis
- easy to read and understand at a glance
- sharable on both client & server for latency compensation
You can also wrap the Meteor.call
with a facade so you can use Post.create(...)
instead of Meteor.call('Posts.create', {...})
. Worth noting, I don’t have an allow/deny setup for this so all mutations with the standard Comments.insert
, etc… will be denied, forcing them to use the method instead.
var schema = {
createdAt: Date,
ownerId: String,
postId: String,
desc: String,
username: String,
};
Comments = new Mongo.Collection('postComments');
// increment comment count on new comment
Comments.after.insert(function (userId, doc) {
Meteor.call('Post.increment', doc.postId, 'commentCount');
});
Meteor.methods({
/**
* Creates a Comment document
* @method
* @param {object} data - data to insert
* @returns {string} of document id
*/
"Comment.create": function(data) {
var docId;
if (User.loggedOut()) throw new Meteor.Error(401, "Login required");
data.ownerId = User.id();
data.createdAt = new Date();
// Schema check, throws if it doesn't match
check(data, schema);
docId = Comments.insert(data);
console.log("[Comment.create]", docId);
return docId;
},
/**
* Updates a Comment document using $set
* @method
* @param {string} docId - The doc id to update
* @param {object} data - data to update
* @returns {number} of documents updated (0|1)
*/
"Comment.update": function(docId, data) {
var optional = Match.Optional;
var count, selector;
if (User.loggedOut()) throw new Meteor.Error(401, "Login required");
check(docId, String);
data.updatedAt = new Date();
check(data, schema); //throws if it doesn't match
// if caller doesn't own doc, update will fail because fields won't match
selector = {_id: docId, ownerId: User.id()};
count = Comments.update(selector, {$set: data});
console.log("[Comment.update]", count, docId);
return count;
},
/**
* Destroys a Comment
* @method
* @param {string} docId - The doc id to destroy
* @returns {number} of documents destroyed (0|1)
*/
"Comment.destroy": function(docId) {
check(docId, String);
if (User.loggedOut()) throw new Meteor.Error(401, "Login required");
// if caller doesn't own doc, destroy will fail because fields won't match
var count = Comments.remove({_id: docId, ownerId: User.id()});
console.log("[Comment.destroy]", count);
return count;
}
});