Creating and Calling a Secure Meteor Server Method to Insert Data
Learn how to create a Meteor server method that validates input, checks user authentication, inserts a document safely, and returns its _id to the client.
04 Jul 2025, 17:55 UTC

Desired Outcome
You want to let a client insert a document into a MongoDB collection while keeping the insertion logic and validation on the server, preventing unauthorized or malformed data from reaching the database.
Prerequisites
- A Meteor project created with
meteor create my-app. - A MongoDB collection defined (e.g.,
Tasks = new Mongo.Collection('tasks');) in a file that loads on both client and server. - The
checkpackage added (meteor add check) for argument validation. - Basic familiarity with running
meteor runand opening the browser console.
Define the Server Method
Create a method that validates its arguments, ensures the caller is logged in, and inserts the document. Return the generated _id so the client can use it optimistically.
// imports/api/tasksMethods.js
import { Meteor } from 'meteor/meteor';
import { Tasks } from './tasksCollection.js';
import { check } from 'meteor/check';
Meteor.methods({
'tasks.insert'(text) {
// Validate that the argument is a non‑empty string
check(text, String);
if (!text.trim()) {
throw new Meteor.Error('invalid-text', 'Task text must not be empty');
}
// Ensure the user is authenticated
if (!this.userId) {
throw new Meteor.Error('not-authorized', 'You must be logged in to add a task');
}
// Insert the document and return its _id
const taskId = Tasks.insert({
text,
createdAt: new Date(),
owner: this.userId,
});
return taskId;
},
});
Place the Method File
Save the file in a directory that loads only on the server, for example server/tasksMethods.js or inside a if (Meteor.isServer) {} block. This prevents the method code from being sent to the client.
Call the Method from the Client
On the client, invoke the method with Meteor.call and handle the callback. Use the returned _id to update the UI optimistically or to show an error.
// client/taskForm.js
import { Meteor } from 'meteor/meteor';
function addTask(text) {
Meteor.call('tasks.insert', text, (error, result) => {
if (error) {
alert(`Insert failed: ${error.reason}`);
} else {
console.log('Task inserted with id:', result);
// Example optimistic UI update
const task = { _id: result, text, createdAt: new Date() };
// Insert into a local Minimongo collection or update UI state
}
});
}
Expected Checks
- Run the app:
meteor run. - Open the browser console and execute
Meteor.call('tasks.insert', 'Test task', console.log);. - Verify that a new document appears in the
Taskscollection (you can inspect viaMongo.Collection.get('tasks').find().fetch()in the console). - Confirm the callback receives the inserted
_id. - Test validation: call with an empty string or a non‑string value and ensure the error is returned to the client.
- Test authentication: log out (or call
Meteor.logout()) and repeat the call; you should receive anot-authorizederror.
Recovery Options (Rollback)
Because the method inserts data, you can remove a test document after verification:
// In the browser console, after noting the _id from the successful call: Tasks.remove('INSERTED_ID_HERE');If you need to disable the method temporarily, comment out the
Meteor.methodsblock in the server file and restart the app; client calls will then return an error indicating the method is missing, confirming that the method is the sole insertion path.Limitations
This guide assumes a simple insert operation. For more complex transactions (e.g., multiple related inserts), consider using Meteor’s
applywithreturnStubValue: trueor a dedicated transaction pattern. Always keep validation inside the method; client‑side checks are for user experience only and cannot guarantee security.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.