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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With