The first version of Express.js was published by TJ Holowaychuk 16 July in 2010 about a year after initial Node.js release. That time Node.js was like a toy, everyone touched it, but was afraid to use in serious projects. The main usage of it was mostly small HTTP services.
Now it’s 2016, time of ES6, JS is everywhere, MEAN stack has become popular and server applications based on Node.js have tons of code. But still everyone uses Express as a industry standard, building crutches around it, but sacredly believes that Express is what we must have.
Connect.js, which is used by Express, uses middlewares and global application as a main idea. And exactly this approach is the evil, which makes a lot of mess in modern Node projects. Let’s look why.
When you have a small app which is basically a HTTP server, it’s quite obvious to have server object as a global state. But in case of complex services HTTP, server is just one part of application. Using Express middlewares you have to use this global object to store state with various of imlicit methods spreading all around the application.
- Collisions, when one middleware can depend on another one
- Needs to mock the global object to be able test every component
- No control over the global object mutations => potential traps.
Middleware design actively uses Node callback notation. At the same time many of middlewares are just simple synchronous functions. And you have to return value with callbacks (next), just because of framework design. WTF?
Now it’s pretty clear, that JS is moving to the getting rid of callbacks completely. Promises are already implemented and we are waiting async/await implementation this year. That means, that libraries that used callbacks must die.
But in case of Express it’s implemented too deeply in framework design and you can avoid callbacks just with dozens on crutches. So Express
- Breaks promises application design
- Forces you to use sync callbacks, which is ridiculous
After Express had moved to Strong Loop there happened a crack in community. The result of that is
Koa is a new framework, that is pretty similar to Express (basically maintained by the old team), except of following:
- Generators instead of callbacks
- Context namespaces to have more controll over global state
- Kinda natural exceptions inside the middlewares
This is a good direction, but still looks like a compromiss.
Unfortunately other solutions (HAPI, RESTify etc) are even worse.
Maybe it’s time to try something new instead of middleware pattern?