Turning promises into responses

facebooktwittergoogle_pluslinkedin

 

Sequelize. The Node.js ORM

The Node.js ORM

I have been doing a lot of Node.js development lately. The eco-system for Node.js is growing with every day and one great gem in the list of awesome modules has been Sequelize. For one of the applications I had to migrate to the latest version of Sequelize (from 1.7 to 2.0). One of the major changes was the switch from callbacks to promises.

There are various discussions out there that try to evaluate one approach versus the other. More importantly than this whole discussion, I’d rather look into how to make it consistent within one application. In this case I looked into convenient ways to make the promises from Sequelize compliant with the callback-style response handlers in Express.

Status quo

So prior to Sequelize 2.0.0 my response handler might have looked something like this:

function getAllUsers(req, res, next) {
	user.findAll().success(function (result) {
		res.json(200, result);
	}).error(function (error) {
		next(error);
	});
}

userController.js, before Sequelize 2.0.0

Straightforward approach

Bluebird promise library

Bluebird promise library

Migrating that is rather straightforward. Sequelize uses Bluebird as the implementation for promises. Instead of a object with two callbacks success and error, it returns a single promise on which we can define a resolution and reject handler with then().

The migrated express handler might then look as follows:

function getAllUsers(req, res, next) {
	user.findAll().then(function (result) {
		res.json(200, result);
	}, function (error) {
		next(error);
	});
}

userController.js, after Sequelize 2.0.0

Using a middle-ware function

This works and is barely different from the first version. But now we often write the same pattern in each handler: On successful resolution we send the result to the client. On rejection we call the error handler.

I tried to simplify this a bit more and came up with the following solution: In our Express middle-ware we can add a function that waits for the resolution of the promise and then handles it appropriately. This looks as follows:

app.use(function (req, res, next) {
	res.promise = promiseResolver(req, res, next);
	next();
});

function promiseResolver(req, res, next) {
	return function (status, promise) {
		promise.then(function (result) {
			res.json(status, result);
		}, function (error) {
			next(error);
		});
	}
}

app.js, or wherever you configure Express

Now we can use this function in our handler:

function getAllUsers(req, res, next) {
	res.promise(200, user.findAll());
}

userController.js, with the new function

I enjoy this one-liner rather much. Let me know if there is a neater solution to this!