Migrating from asp.mvc application to node.js application with a focus on design

Migrating from asp.mvc application to node.js application with a focus on design

Problem

I am currently looking into alternative platforms to migrate an existing application onto, it started out as a prototype using asp.mvc but the majority of code is javascript with a simple asp mvc web service so as we are looking at taking it forward it seems sensible that we just scrap the current microsoft stack and just go for nodejs giving us more freedom of where and how we host our application, also we can reuse some of the models and code in both the web service and front end, although this would probably end up being a small amount.

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/1 and have the user object pulled out and update the user with id 1 in the database (which we will talk about shortly).

  • What is the best way to validate the data being sent over? Currently in our front end javascript application we use KnockoutJS and all models use knockout observables and are validated using Knockout.Validation. I am happy to use Knockout Validation on node as the models are the contract between the front end and back end, however if there is a better solution I am happy to go look into it.

Database Interactions

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.

Testing

Currently there is Unit, Integration, Acceptance testing within the application. The Unit tests happen on both the front end and back end, so currently it will do javascript tests using JsTestDriver in our build script to confirm all the business logic works as intended in isolation etc. Then we have integration tests which currently are all done in C# which will test our controllers and actions work as expected as well as any units of work etc, this again is kicked off by the build script but can also be run via the Resharper unit test runner. Then finally we have acceptance tests which are written in c# using web driver which just target the front end and test all the functionality via the browser. My main concerns around this are:

  • 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.

Problem courtesy of: Grofit

Solution

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.

Solution courtesy of: dankohn

Discussion

Leave a Reply

Your email address will not be published. Required fields are marked *