Node.js @Toyota Europe
Already Nicely Done
- 12Factor
- Explicit connections & startup
- Custom modules
- Tridion
Error Handling
Suggestions
// instead of:
if (util.isError(err) && (err.message !== ''))
// use just:
if (err)
// instead of:
next(err)
// use:
return next(err) // ditto for other callbacks
// either throw or call back, but never both:
callback(err);
throw err;
// instead of anonymous functions:
function(cb) {}
// always name functions for better traceability:
function loadConfig(cb) {}
// instead of:
init(function startServer(db) {
// always send (err) as the first argument to any callback:
init(function startServer(err, db) {
Even further...
- Domains: you probably don't want to use this
- Wrapping: https://github.com/davepacheco/node-verror#werror-wrap-layered-errors
Performance
(& flow control)
Useful flow modules
- vasync (https://github.com/davepacheco/node-vasync)
- connect-parallel (https://github.com/Applifier/connect-parallel)
- promises (https://github.com/then/promise)
In general, parallel-ize wherever possible.
"Iceberg" organization
// this is the business logic you care about
vasync.parallel([ foo, bar, biz, baz ], onComplete);
// forces another good convention: no anonymous functions!
function foo(done) { }
function bar(done) { }
function biz(done) { }
function baz(done) { }
function onComplete(err, results) { }
Cluster
- Always cluster (with 1...N workers)
- Consider a tested worker-forking module (https://github.com/hunterloftis/throng ... recently hacked together for DevCenter)
(there are a million others)
Raise maxSockets
http.globalAgent.maxSockets = Infinity;
console.log == slow
consider 'verbose' or 'quiet' env vars (investigating streaming to stdout atm)
Testing
Useful Modules
- Mocha
- var assert = require('chai').assert
- Nock
- Supertest
Other suggestions
- Consider virtual machines / vagrant
- Add a .jshintrc to the module root
- Smaller modules = more likely to be tested
- "Pyramid" testing - isolate business logic at the base
Avoid if possible
- Domains
- Anonymous functions
- 'Pyramid of Doom'
- Modules > 300 LoC
- Optimization
Facade / API Orchestration
- Request (https://github.com/mikeal/request)
- Superagent* (https://github.com/visionmedia/superagent)
- Compose Router instances (http://expressjs.com/api#router)
- Understand the separate 'error stack' middleware
Large App Patterns
The Wrapped App
- Almost there already (t1-modules)
- Goal is to separate business concerns & http concerns
- https://github.com/hunterloftis/node-production/blob/master/lib/web/index.js#L18
Worker Queues
- https://devcenter.heroku.com/articles/asynchronous-web-worker-model-using-rabbitmq-in-node
- Redis, RabbitMQ, IronWorker...
Message Brokers
- Fred George - good explanation of microservices
- Use a message broker (eg, amqp) to communicate between lots of independent services via messages. Page renderer -> "I need options for car X", Car Configurator -> "Options for car X: blah" ... Page renderer has a timeout and renders with whatever data is available after, say, 300ms.
Want more hands-on help?
Happy to connect you with trusted Node.js dev partners.
Node.js @Toyota Europe
By hunterloftis
Node.js @Toyota Europe
- 1,394