Author: David Fekke
Published: 1/13/2016
After programming in an object oriented way for 15 years, I am started to make the transition of programming in a more functional way
with languages like Javascript and Swift. Javascript has always treated functions as first class citizens, and their is a movement in
the Javascript community from developers such as Eric Elliot to never use the new
keyword again.
I recently upgraded an express site from 3 to version 4. As part of that process I decided to refactor the code that called external services so they would be more testable and more loosely coupled. In languages such as Java and C# this can be achieved by using dependency injection.
In express it is actually very easy to inject functionality into a route. This can be done by either using middleware or injecting another function into a route.
const routes = require('./routes/index');
const exposeService = function(req, resp, next){
req.service = require('./myservice');
next();
};
app.use('/', exposeService, routes);
For one of the routes I needed to be able to inject two services that could be used by the route. In an earlier version of the combined service I created an object that had two properties that held references to other objects that had functions for returning the data I needed in my route. Here is how I intially wrote the service as an object.
"use strict";
// Creating function object
const Service = function Service(meetupdata, twitterdata) {
this.Meetup = meetupdata;
this.Twitter = twitterdata;
}
// Prototype function for getting the next meeting
Service.prototype.getNextMeetup = function getNextMeetup(cb) {
this.Meetup.getNextMeetup(cb);
};
// Prototype function for getting the tweets
Service.prototype.getTweets = function getTweets(cb) {
this.Twitter.getFeed(cb);
};
// factory function for creating a new version of the object
function create(meetupdata, twitterdata) {
return new Service(meetupdata, twitterdata);
}
module.exports = create;
While this worked, it turns out there is a much simpler and more elegant way of creating this service.
"use strict";
function Service(meetupDataFN, twitterDataFN) {
return {
getNextMeetup: meetupDataFN,
getTweets: twitterDataFN
}
}
module.exports = Service;
Summary
In the current version of my service I am returning an object with two functions. Not only is this approach cleaner, it is also more functional. I am also just passing in functions instead of whole objects.