This will probably be quite a large question encompassing many parts but I will put it out there anyway as I am sure this could be helpful to lots of other people looking at how they can move from something like .net/java to to node.js. As most of these statically typed languages have lots of patterns and practices used, such as Inversion of Control, Unit of Work, Aspect Oriented Programming etc it seems a bit strange moving towards another platform which doesn’t seem to require as much structure in this area… So I have some concerns about migrating from my super structured and tested world to this new seemingly unstructured and dynamic world.
So here are the main things I would do in MVC and would want to do in node.js currently but am not quite sure the best way to achieve the same level of separation or functionality.
Routing to Actions
This mechanism in ASP MVC seems to be replaceable by Express in node.js, which will give me the same ability to map a route to a method. However there are a couple of concerns:
in ASP MVC my controllers can be dependency injected and have variables so actions are easy to test as everything they depend on can be mocked when needed and passed in via constructor. However as the method in express seems to not have a containing scope it seems like I would have to either use global variables or new up the variables internally. Is there a nice way to access my business logic containers in these routed methods?
Is there any way to autobind the model being sent? or at least get the json/xml etc in some useful manner? It appears that if you send over the correct mime type with the content it can be extracted but I have not seen any clear examples of this online. I am happy to use additional frameworks on top of Express to provide this functionality, as ideally I just want to make a POST request to
/user/1and have the user object pulled out and update the user with id 1 in the database (which we will talk about shortly).
Currently in .net land we use NHibernate for communicating with our relational databases and the MongoDB driver for communicating with our MongoDB Databases. We use a Generic Repository pattern and isolate queries into their own classes. We also use a Unit Of Work pattern quite heavily so we can wrap logical chunks of word into a transaction and then either commit it all if it goes well or roll back if it doesn’t. This gives us the ability to mock out our objects at almost any level depending on what we want to test and also lets us change our implementations easily. So here is my concern:
- Sequalize seems to be a good fit for replacing NHibernate, however it doesn’t seem to have any sort of transaction handling making it very difficult to make a unit of work pattern. This is not the end of the world if it cannot be done in the same way, but I would like some way of being able to group a chunk of work in some way, so an action like CreateNewUserUnitOfWork which would take a model representing the users details, validate it, create an entry in one table, then create some relational data in others etc, get the users id from the database and then send that back (assuming all went well). From looking at the QueryChainer it seems like it provides most of the functionality but if it failed on the 3rd of 5 actions it doesn’t appear simple to roll back, so is there some way to get this level of control?
Plugins / Scattered Configuration Data
This is more of a niche concern of our application, but we have the central application then other dlls which contain plugins. There are dropped into the bin folder and will then be hooked in to the routing, database and validation configuration. Imagine it like having the google homepage, and google maps, docs etc were all plugins which told the main application to route additional calls to methods within the plugin, which then had their own models and database configurations etc. Here is my concern around this:
- There seems to be a way to update the routing by just scanning a directory for new plugins and including them (node.js require all files in a folder?) but is there some best practice around doing this sort of thing as I don’t want each requestto have to constantly do directory scans. It is safe to assume that I am happy to just have the plugins in their right places at the time of starting the node application so no need to add plugins at runtime at the moment.
What is the best practice and frameworks for testing nodejs? Currently most of the tests which test at the ASP layer are carried out via C# scripts creating the controller with mocked dependencies and running the actions to prove it works as intended using MVC Helpers etc. However I was wondering what level of support NodeJS has around this, as it doesn’t seem simple (on a quick glance) to test node.js components without having node running.
Assuming there is some good way to test node.js can this be hooked into build scripts via command line runners etc? as we will want everything automated and isolated wherever possible.
I appreciate that this is more like 5+ smaller questions rolled up into one bigger question but as the underlying question is how to achieve good design with a large node js application I was hoping this would still be useful to a lot of people who like myself come from larger enterprise applications to node js style apps.
I recently recently switched from ASP MVC to Node.js and highly recommend switching.
I can’t give you all the information you’re looking for, but I highly recommend Sequelize as an ORM and mocha (with expect.js and sinon) for your tests. Sequelize is adding transaction support in the next version, 1.7.0. I don’t like QueryChainer since each of it’s elements are executed separately.
I got frustrated with Jasmine as a test framework, which is missing an AfterAll method for shutting down the Express server after acceptance tests. Mocha is developed by the author of Express.
If you want to have an Express server load in plugins, you could use a singleton pattern like this: https://github.com/JeyDotC/articles/blob/master/EXPRESS%20WITH%20SEQUELIZE.md
You will probably will also really like https://github.com/visionmedia/express-resource which provides a RESTful interface for accessing your models. For validation, I think you’ll be happy with https://github.com/ctavan/express-validator
Why would you need to test Node modules without using Node? It’s considered standard to call a test script with a Makefile, and you can add a pre-commit hook to git to run the tests before making a commit.