Skip to content

Instantly share code, notes, and snippets.

@ArnaudWopata
Last active August 29, 2015 14:07
Show Gist options
  • Save ArnaudWopata/8472f35350a7031e2cb2 to your computer and use it in GitHub Desktop.
Save ArnaudWopata/8472f35350a7031e2cb2 to your computer and use it in GitHub Desktop.
Clean Express controllers using currying and promises

Purpose

Demonstrate how to write clean express controllers using function currying and promises.

  • Promises helps avoiding callback hell
  • Currying helps code reuse

Install, run, test

git clone https://gist.github.com/8472f35350a7031e2cb2.git express_curry_promise
cd express_curry_promise
npm install
node app.js

... in another shell

curl -v http://localhost:3000/flip/head
curl -v http://localhost:3000/flip/tail
curl -v http://localhost:3000/flip/head
curl -v http://localhost:3000/flip/tail

var express = require('express');
var app = express();
var flipController = require('./flip_controller');
app.get('/flip/:bet', flipController.get);
app.listen(3000);
var Promise = require('bluebird'); // Awesome promise library
module.exports = function(bet){
var result = Math.round(Math.random()) ? 'head' : 'tail';
var responder = result === bet.toLowerCase() ? Promise.resolve : Promise.reject;
return responder({
success: result === bet,
bet: bet,
result: result
});
};
var _ = require('lodash'); // underscore++
var flipCoin = require('./flip_coin'); // Your actual handler, usually async
var respond = _.curry(function(res, status, payload){
console.log('responding [%s] result:', status, payload);
res.status(status).send(payload).end();
});
var controller = {
get: function(req, res){
var bet = req.params.bet;
if(
typeof bet !== 'string' || (
bet.toLowerCase() !== 'head' &&
bet.toLowerCase() !== 'tail'
)
){
respond(res, 400, {
message: 'missing or incorrect parameter `bet`, expects "head" or "tail" string'
});
return;
}
flipCoin(bet)
.then(respond(res, 200)) // on success, send a 200 and forward flipCoin result
.catch(respond(res, 403));// on error, send a 403 and forward flipCoin result
}
}
module.exports = controller;
{
"name": "curry_promise_express",
"version": "1.0.0",
"description": "Example of clean Express controllers using currying and promises",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://gist.github.com/8472f35350a7031e2cb2.git"
},
"keywords": [
"curry",
"express",
"promise"
],
"author": "Arnaud Rinquin",
"license": "MIT",
"dependencies": {
"bluebird": "^2.3.6",
"express": "^4.9.8",
"lodash": "^2.4.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment