Structuring our meteor model packages
I’ve been working with meteor for almost 2 years. During that time I’ve lived many big changes and I’ve been adapting mmmelon alone (package system, flow router, react…).
Now we’re working hard on adding new features requested by users and also expecting our team to grow, so I decided to start working on a solid base shared in all our model packages. A base that makes me and future programmers easier to work on mmmelon model and also that makes mmmelon ready for future changes in meteor ecosystem.
During this time working with meteor I’ve identified many issues but some key ones are:
- Testing: The best word to describe testing in meteor is Horrible. I hope this gets much better with meteor 1.3 but right now testing hurts.
- Dependencies: Javascript world is moving really fast and meteor is on the top of that world. New things that change all appear every day. Blaze changed and now seems dead. Meteor has already announced that they will add GraphQL with realtime support. This makes using 3rd party dependencies a big risk. You may use a package today that could be broken tomorrow or simply not ready for that X new thing you’ve to do and then you’ll have to change all.
- Blaze/model chaos: It’s really easy to merge your views with model logic, validation… That becomes a big issue when your app grows.
With this in mind I started working on a simple way to structure our model packages. All of them should follow this principles:
- Predictable: It should be easy to see what happened and what would happen.
- Testable: It is easy to unit test 100% of your code.
- Understandable: It should be easy to code and read.
- Encapsulated: Model should only expose what the application needs. Database operations, methods… All should be encapsulated inside the package and never used outside it.
- Meteorized: We’re using meteor for a reason. Model should be based on Latency compensation.
- Secure: Client database operations are bad, always. Any operation from client should be blocked except inserts where you need _id immediately after insert.
- Functional: (Or kind of) Your model should represent the data you save into database but should’t contain methods. Functions never mutate data. This makes it easy to read and test.
This work is published on github so anyone can read and help making it better. Is just a WIP idea of what I think suits best our needs. We’re already adopting it with great results but I’ll love getting other meteorites view on this. Maybe there’s a better way to code following this base principles.
You can check the full spec here.