Mistakes in the first large Meteor project

In the last months, I’ve been working in my first large Meteor project, mine and the company I current work. This application is running over the infrastructure that I posted before “Amazon auto scaling and Meteor”, yes, Galaxy was not available yet 🙂 After some time we realized that even that Meteor do a great job making the complex simple, someone with more experience would be great to point our mistakes and lacks of knowledge. In the first days, this guy “Caio Ribeiro” make a list with improvements that we should do. This list.:

Migrate secret keys from config.js to settings.json

When we just started, our secrets and keys were in config.js file, like that.

Meteor.startup(function () {

    ServiceConfiguration.configurations.upsert(
        { service: "google" },
        {
            $set: {
                clientId: "our client id",
                secret: "our secret"
            }
        }
    );
});

As we aren’t using settings.json to centralize this kind os information, we were spreading this through the source files. After the refactoring, we just use Meteor.settings to get this informations.

Meteor.startup(function () {

    ServiceConfiguration.configurations.upsert(
        { service: "google" },
        {
            $set: {
                clientId: Meteor.settings.google.clientId,
                secret: Meteor.settings.google.secret
            }
        }
    );
});

 

Kadira informations

This situation is similar to previous one, we were using an file called kadira.js to keep Kadira’s app id and app secret. It was not working properly because we ware sending informations to kadira, even when we were in development mode. We just deleted this file and set Kadira’s environment variables in our production machines.

export KADIRA_APP_ID=<App ID>
export KADIRA_APP_SECRET=<App Secret>

 

Create a server/publications directory and split Meteor.publish, one publish per file

Before the refactoring we had a big file called publish.js inside server directory, we wrote all publications there, thousands of lines in the same publish file.

Now we have this directory with many little files named like the publication.

 

Splitting routes files {.p1}

This one is pretty similar to the previous one too, we had two big route files, one with all private routes, another one with all the public routes, we just split it in small files inside two directories, public and private.

Testing

In the very beginning of this project it was just me, alone, taking care of everything, I had to figure out what I need to do, I mean, business rules, I was building a infrastructure at Amazon and writing code. The advantage is that I knew everything, the disadvantage is that it maybe it would take too long. So, 2 new developers join me and them more 5! After that, the system start to grow faster, from a day to another many features just appear and suddenly I just didn’t know the whole system anymore, but it not happens just with me of course, everybody was building new features and… breaking others without knowing. Was a rain of bugs, people almost having heart attack, sad… that same old story. So, this guy, more experienced start to write tests with velocity and jasmine and today I saw some tests accusing errors after a change 🙂 Remember,  If someday someone tell you that tests doesn’t matter, run, as fast, as far as possible.

Removing Collections.allow()

To every single collection, we were doing something like that.:

Categories.allow({
    insert: function(doc){
        return true;
    },
    update: function(doc){
        return true;
    },
    remove: function(doc){
        return true;
    }
});

Doing that is the same of using the insecure package, the solution? Just remove it and write Meteor.methods. In our case, we were doing both, using Collections.allow() and writing methods, in the same place.

Categories = new Mongo.Collection("categories");

Categories.allow({
    insert: function(doc){
        return true;
    },
    update: function(doc){
        return true;
    },
    remove: function(doc){
        return true;
    }
});

Meteor.methods({
    insertCategory: function(newCat){
        var cat = _.extend(newCat,{
            createdAt: new Date(),
            owner: Meteor.userId(),
            updatedAt: null
        });

        var catId = Categories.insert(cat);

        return {
            _id: catId
        }
    },
    updateCategory: function(editCat){
        var cat = _.extend(editCat,{
            updatedAt: new Date()
        });

        var catId = Categories.update(editCat._id,cat);
        return {
            _id: catId
        }
    },
    categoryFindOne: function(id){
        return Categories.findOne({_id:id})
    },
    categoryRemoveOne: function(id){
        Categories.remove({_id:id})
    }
});

 

Migrate sensitive Meteor.methods to server/methods

Another problem related to the previous topic “Removing Collections.allow()” was that our methods containing business rules were on both directory “maybe you are using lib instead”. _The problem is that our method’s codes were exposed to the client, our business rules were visible. The solution was simple, just create a new directory inside server, called _methods and put everything there, that’s it, these codes are safe now 🙂

Conclusion

I hope this informations could be useful for you, even that Meteor looks like pretty easy, good practices are still necessary. But one thing is undeniable, Meteor is really fun and a great option to build playful work environments. By the way, this is the project I’m talking about. https://www.redpass.com.br/ It’s just a pilot for while but soon it’ll be oficial.

Allan de Queiroz

Allan de Queiroz
London based software engineer

XServer forward from Linux text mode for Headless purposes.

Hello, this post is about XServer forward from Linux text mode, **not ssh forward, anything related to VNC** or things like that.Recently...… Continue reading