Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid fat models in a node.js + mongoose app?

The app is using express 3. Here is a barebones example of a route that fetches data from the database:

var Post = mongoose.model('Post')

app.get('post/:id/loompas', function(req, res) {
    Post.getLoompas(function(err, data){
        res.render('x', data)
    })
})

Where Posts.getSomeData is defined as instance methods in /models/post.js, and sometimes accesses external APIs:

PostSchema.method('getLoompas', function(callback){
    var post = this
    API.get('y', function(x){
        this.save(x)
        callback(x)
    })
})

This is starting to smell, and doesn't look like it belongs along the Schema definition. The collection of methods could grow quite large.

What design patterns are recommended to separate these concerns and avoid extremely fat models? A service layer for external API calls? Any interesting solutions out there?

like image 779
Ricardo Tomasi Avatar asked Jan 25 '13 21:01

Ricardo Tomasi


1 Answers

This does indeed smell a little bit. I would use the approach of considering your web app merely as a view of your application.

The best way to ensure this is to never use your mongoose models from your webapp. You could have your webapp living in a process and your model specific logic in another process. The job of that second process would be to take care of your business logic and persistence layer (mongoDB), making it the M in MVC.

Accessing external APIs would take place in that Model layer, we your can separate it from your persistence implementation.

There's a way of communicating between node processes that I like, it's dnode. Once set up, it looks like you are communicating with objects and callbacks within your own process. I would make the webapp and the business app communicating through this in order to get data. The webapp needn't manipulate the actual data and instead sends message to the Model layer (as described by the MVC pattern).

This ensures complete separation between controller/view (webapp) and model+persistence.

One side effect of this organization is that you can easily write other clients of your application, for example a CLI client or a RESTful API.

like image 128
Floby Avatar answered Nov 09 '22 23:11

Floby