nodejs functional programming and schema validation lightning talk
TRANSCRIPT
#1 : SCHEMA VALIDATION
“Good code is its own best documentation.”(Steve McConnell)
Mobile Server – JSON Processor
Mobile Server with Schema Validation
Mobile Client
Validation layer
Mobile Server
• Every request / response goes through validation with schema.• In case of response validation failure, the response is a 500• In case of request validation failure, the response is a 400.
How?
Avro Schema{ "type" : "record", "name" : ”Person", "namespace": "com.linkedin.mobileserver.templates", "doc" : ”Represents all the data fields for a person.", "fields" : [ { "name" : "firstName", "type" : "string", "doc" : "First name of the person" }, { "name" : "lastName", "type" : "string", "doc" : "Last name of the person" }], "version" : 1}
{ firstName: “Deepank”, lastName: “Gupta”}
How can I use it?
• Avro is open-source, available in Apache. Schema details: http://avro.apache.org/docs/current/spec.html
• Node module for helping with Avro:https://npmjs.org/package/avro-schema
#2: FUNCTIONAL PROGRAMMING
"It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures."
—Alan Perlis
Pure vs Impure Functions
function add(a, b) { return a + b;}
function getFirst(name) { return name.slice(0, 1)[0];}
var x;function add() { x = this.a + this.b;}
function getFirst(name) { return name.splice(0, 1)[0];}
Why?
• Easy to use & understand• Simple to test. No before clauses required to
setup big objects.• No coupling
Higher Order Functions
• What?– Functions that accept functions as parameters or
return functions– Yes… functions are just like any other data
• Why?– Code Reuse– Terse, beautiful code
Functions that take a function as input
var res = [];var l = arr.length; for (var i = 0, i < l; ++i) { res.push(arr[i]);}
var res = _.map(arr, function(e){ return e;});
Example without Higher Level functionsfunction getProfile(req, res) { ProfileHelper.get(req, function(err, result) { if (err) { var error = getError(500, {msg: err}); Util.sendError(req, res, error); } else { Util.sendJsonResponse(req, res, result); } });}
function getUpdates(req, res) { UpdatesHelper.get(req, function(err, result) { if (err) { var error = getError(500, {msg: err}); Util.sendError(req, res, error); } else { Util.sendJsonResponse(req, res, result); } });}
Example with higher order functionfunction getProfile(req, res) { ProfileHelper.get(req, jsonResponder(req, res, 500));}
function getUpdates(req, res) { UpdatesHelper.get(req, jsonResponder(req, res, 400));}
function jsonResponder(req, res, errorKey) { return function(err, result) { if (err) { var error = getError(errorKey, {msg: err}); Util.sendError(req, res, error); } else { Util.sendJsonResponse(req, res, result); } });}
Functional libraries & resources
• Underscore.js (http://underscorejs.org )• lodash.js (http://lodash.com )• Wu.js (http://fitzgen.github.com/wu.js )