node.js middleware and js encapsulation - node.js

I'm new to javascript, and jumped right into node.js. I've read a lot of theory, and began well with the practical side (I'm writing an API for a mobile app), but I have one basic problem, which has lead me to middleware. I've successfully implemented a middleware function, but I would like to know if the use I'm giving the idea of middleware is OK, and also resolve the original problem which brought me to middleware. My question is two-fold, it's as follows:
1) From what I could gather, the idea of using middleware is repeating a process before actually processing the request. I've used it for token verification, as follows:
Only one of my urls doesn't receive a token parameter, so
app.js
app.get('/settings', auth.validateToken, auth.settings);
auth.js
function validateToken(req, res, next){ //code };
In validateToken, my code checks the token, then calls next() if everything is OK, or modifies res as json to return a specific error code.
My questions regarding this are: a) Is this a correct use of middleware? b) is there a [correct] way of passing a value onto the next function? Instead of calling next only if everything is OK, is there a [correct] way of calling next either way, and knowing from inside the next function (whichever it is), if the middleware was succesful or not? If there is, would this be a proper use of middleware? This precise point brings me to my original problem, and part two of this question, which is encapsulating functions:
THIS PART WAS FIXED, SEE MY SECOND COMMENT.
2) I discovered middleware trying to simply encapsulate validateToken, and be able to call it from inside the functions that the get handlers point to, for example auth.settings.
I'm used to common, sequential programming, and not in javascript, and haven't for the life of me been able to understand how to do this, taking into account the event-based nature of node.js.
What I want to do right now is write a function which simply verifies the user and password. I have it perfectly written inside a particular handler, but was about to copy-paste it to another one, so I stopped. I want to do things the right way from scratch, and understand node.js. One of the specific problems I've been having, is that the error code I have to return when user and password don't match are different depending on the parent function, so I would need this function to be able to tell the callback function "hey, the password and user don't match", so from the parent function I can respond with the correct message.
I think what I actually want is to write an asynchronous function I can call from inside another one.
I hope I've been clear, I've been trying to solve this on my own, but I can't quite finish wrapping my head around what my actual problem is, I'm guessing it's due to my recent introduction to node.js and JS.
Thanks in advance! Jennifer.

1) There is res.locals object (http://expressjs.com/api.html#res.locals) designed to store data local to the request and to pass them from one middleware to another. After request is processed this object is disposed of. If you want to store data within the session you can use req.session.
2) If I understand your question, you want a function asynchronously passing the response to the caller. You can do it in the same way most node's functions are designed.
You define a function in this way:
function doSomething(parameters, callback) {
// ... do something
// if (errorConddition()) err = errorCode();
if (callback) callback(err, result)
}
And the caller instead of using the return value of the function passes callback to this function:
function caller(req, res, next) {
//...
doSomething(params, function(err, result) {
if (! err && result) {
// do something with the result
next();
} else {
// do something else
next();
// or even res.redirect('/error');
}
});
}
If you find yourself writing similar callback functions you should define them as function and just pass the function as parameter:
//...
doSomething(param, processIt);
function processIt(err, result) {
// ...
}
What keeps you confused, probably, is that you don't treat functions as values yet, which is a very specific to JavaScript (not counting for languages that are little used).

In validateToken, my code checks the token, then calls next() if everything is OK, or modifies res as json to return a specific error code.
a) Is this a correct use of middleware?
b) is there a [correct] way of passing a value onto the next function?
Yes that is the correct way of using middleware, although depending on the response message type and specifications you could use the built in error handling of connect. That is in this example generate a 401 status code by calling next({status:401,stack:'Unauthorized'});
The middleware system is designed to handle the request by going through a series of functions until one function replies to the request. This is why the next function only takes one argument which is error
-> if an error object is passed to the next function then it will be used to create a response and no further middleware will be processed. The manner in which error response is created is as follows
// default to 500
if (res.statusCode < 400) res.statusCode = 500;
debug('default %s', res.statusCode);
// respect err.status
if (err.status) res.statusCode = err.status;
// production gets a basic error message
var msg = 'production' == env
? http.STATUS_CODES[res.statusCode]
: err.stack || err.toString();
-> to pass values down the middleware stack modifying the request object is the best method. This ensures that all processing is bound to that specific request and since the request object goes through every middleware function it is a good way to pass information down the stack.

Related

Express route with multiple middlewares and separated layers

I'm reading the GitHub https://github.com/goldbergyoni/nodebestpractices and trying to apply the tips on my project. Currently i'm working on the "1.2 Layer your components, keep Express within its boundaries" tip, but I have a question.
I'm using routes/controllers, and using this tip (1.2), a route with multiple middlewares will look like this.
router.post("/do-multiple-stuff",
(req, res, next) => {
stuffController.getStuffDone(req.body.stuff);
next();
},
(req, res, next) => {
stuffController.getOtherStuffDone(req.body.otherStuff);
return res.send("stuff done");
});
Is this correct? Or there's a better way to do this?
Thanks! <3
The point of that 1.2 section is to create your business logic as a separate, testable component that is passed data only, not passed req and res. This allows it to be independently and separately tested without the Express environment around it.
Your calls to:
stuffController.getStuffDone(req.body.stuff);
and
stuffController.getOtherStuffDone(req.body.otherStuff);
Are indeed making that proper separation between the web and the business logic because you aren't passing req or res to your controller. That looks like it meets the point of the 1.2 training step.
The one thing I see missing here is that there isn't any output from either of these function calls. They don't return anything and since you don't pass req or res to them, they can't be modifying the req object (like some middleware does) and can't be sending a response or error by themselves. So, it appears that these need a mechanism for communicating some type of result back, either a direct return value (if the functions are synchronous) or returning a promise (if the functions are asynchronous). Then, the calling code could get their result and do something with that result.

nodeJS callback error parameter

I'm learning node now and I'm confused about the err parameter.
I thought it's supposed to be the first argument of a callback function but I don't see it in many call back functions. Can anyone explain it to me? Thanks!
There's many different kinds of functions and callback functions in particular. The Node.js standard for callback functions is those of the form:
function(err, arg1, arg2, ...)
Where arg1 and so forth are only present if relevant but the err argument is always first. This is the reverse of a lot of historical JavaScript code where errors would be the last argument.
The Node.js method of forcing the error as the first argument even if there's no error makes ignoring errors harder, you rarely forget to declare that argument, and makes their location predictable.
Now this only applies in the case of a general-purpose callback. That is, there are occasions where calling a function will trigger a singular callback at some point in the future. You'll see them used like this:
doStuff(function(err, successValue) { ... });
There's also the style popularized by jQuery where one or more of your callbacks will be triggered depending on the outcome of the operation:
doStuff({
success: function(successValue) { ... },
error: function(err) { ... },
timeout: function() { ... }
});
Note that in this case you may have both the error and timeout callbacks being fired. You're not obligated to populate all of these, either.
The downside to this approach is the unpredictability of which ones get called and the risk of handling something twice inadvertently.
The error parameter is usually for asynchronous code.
node errors
Most asynchronous methods that accept a callback function will accept an Error object passed as the first argument to that function. If that first argument is not null and is an instance of Error, then an error occurred that should be handled.
app.get() sends get request and return an error like a 404
and you could do something like this res.status(404).render( in app.get()
Express error handling
error-handling functions have four arguments instead of three: (err, req, res, next)
The reason why some code uses err as the first parameter is because some code like fs.readFileis programmed to check if there was an error and to handle it. The author of the API specifically wrote code to check the first argument for an error and handle it.
That's why it is available to you for some methods an unavailable for other methods.
First: a callback is just a function. Different callbacks serve different purposes.
In general, a function that performs an asynchronous action and should "return" a value gets passed a callback function that will take (at least) two arguments: the first is used to pass errors (if any), the second (and following) are used to pass the value(s) that should be returned to the caller.
You noticed that net.createServer() will also take a callback function, but that function only has one argument.
That's because, in this case, the callback isn't used to pass errors and/or values. Instead, it's a function that gets called when a new connection is made to the server.
It's really a bit of a shortcut. This code:
var server = net.createServer(function(connection) {
...
});
Is short for this code:
var server = net.createServer();
server.on('connection', function(connection) {
...
});

node.js - perform global procedure before invoke the mapped methods

everyone ! I've this sentence in my app.js:
app.get('/aux/:subject/:data', aux.query);
app.post('/register/:Id', register.create);
app.post('/register/:Id/smsConfirm', register.confirmSms);
app.post('/register/:Id/login', register.login);
app.post('/register/:Id/resetPassword', register.resetPassword);
app.get('/register/:Id/getSms', register.getSms);
And I will have much more because it's the beginning. And i'd like to implement a global function to be executed before any class like aux.query, register.create, etc be invoked.
Basically I'd like to check if the IP is on my black list. If true: Don't execute anything - Throw a 403 instead.
Actually the only way I know to implement this is to put in any method a verification using promises and after check, allow the execution, but I believe that there is a better way to do the things in a global way (maybe not ??)
Can someone give me a good hint ? ty !
You should handle your black list check as middleware if it is a valid test for every endpoint.
function blacklist(req, res, next) {
// check blacklist
// call next() if passed
next();
}
app.use(blacklist);
app.get('/aux/:subject/:data', aux.query);
app.post('/register/:Id', register.create);
app.post('/register/:Id/smsConfirm', register.confirmSms);
app.post('/register/:Id/login', register.login);
app.post('/register/:Id/resetPassword', register.resetPassword);
app.get('/register/:Id/getSms', register.getSms);

To async, or not to async in node.js?

I'm still learning the node.js ropes and am just trying to get my head around what I should be deferring, and what I should just be executing.
I know there are other questions relating to this subject generally, but I'm afraid without a more relatable example I'm struggling to 'get it'.
My general understanding is that if the code being executed is non-trivial, then it's probably a good idea to async it, as to avoid it holding up someone else's session. There's clearly more to it than that, and callbacks get mentioned a lot, and I'm not 100% on why you wouldn't just synch everything. I've got some ways to go.
So here's some basic code I've put together in an express.js app:
app.get('/directory', function(req, res) {
process.nextTick(function() {
Item.
find().
sort( 'date-modified' ).
exec( function ( err, items ){
if ( err ) {
return next( err );
}
res.render('directory.ejs', {
items : items
});
});
});
});
Am I right to be using process.nextTick() here? My reasoning is that as it's a database call then some actual work is having to be done, and it's the kind of thing that could slow down active sessions. Or is that wrong?
Secondly, I have a feeling that if I'm deferring the database query then it should be in a callback, and I should have the actual page rendering happening synchronously, on condition of receiving the callback response. I'm only assuming this because it seems like a more common format from some of the examples I've seen - if it's a correct assumption can anyone explain why that's the case?
Thanks!
You are using it wrong in this case, because .exec() is already asynchronous (You can tell by the fact that is accepts a callback as a parameter).
To be fair, most of what needs to be asynchronous in nodejs already is.
As for page rendering, if you require the results from the database to render the page, and those arrive asynchronously, you can't really render the page synchronously.
Generally speaking it's best practice to make everything you can asynchronous rather than relying on synchronous functions ... in most cases that would be something like readFile vs. readFileSync. In your example, you're not doing anything synchronously with i/o. The only synchronous code you have is the logic of your program (which requires CPU and thus has to be synchronous in node) but these are tiny little things by comparison.
I'm not sure what Item is, but if I had to guess what .find().sort() does is build a query string internally to the system. It does not actually run the query (talk to the DB) until .exec is called. .exec takes a callback, so it will communicate with the DB asynchronously. When that communication is done, the callback is called.
Using process.nextTick does nothing in this case. That would just delay the calling of its code until the next event loop which there is no need to do. It has no effect on synchronicity or not.
I don't really understand your second question, but if the rendering of the page depends on the result of the query, you have to defer rendering of the page until the query completes -- you are doing this by rendering in the callback. The rendering itself res.render may not be entirely synchronous either. It depends on the internal mechanism of the library that defines the render function.
In your example, next is not defined. Instead your code should probably look like:
app.get('/directory', function(req, res) {
Item.
find().
sort( 'date-modified' ).
exec(function (err, items) {
if (err) {
console.error(err);
res.status(500).end("Database error");
}
else {
res.render('directory.ejs', {
items : items
});
}
});
});
});

Is Next Bad to Use if I Don't Need it?

In express and connect, is it bad to use "next" in middleware if I do not need it? Are there any possible negative outcomes? Assume there is no middleware which will be called after this middleware, and therefore the next will not call anything. I know it is bad for modularity, as if you want to add a callback for another middleware it may be accidentally triggered by the next in this middleware. However, in this case next is bad for modularity anyway, as middleware often interact in unexpected ways.
As an example of an unneeded next, consider the sample MEAN.JS stack, constructed by the guys who originally came up with the stack's name. It seems to have some next callbacks which do not ever get called. Many are in the users controller, including the signin function:
exports.signin = function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err || !user) {
res.status(400).send(info);
} else {
// Remove sensitive data before login
user.password = undefined;
user.salt = undefined;
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
} else {
res.json(user);
}
});
}
})(req, res, next);
};
This function has a next callback defined. This next callback is then used by the passport.authenticate() custom middleware function as a parameter. However, this parameter is never used in the function itself. I have tried taking out the next definition from the function definition, as well as the custom passport middleware, and the route seems to still work. However, perhaps passport uses it in its authenticate() function, and leaving it out did not cause any trouble here but it may cause trouble in some cases.
I was recently looking at passport's tutorials on http://passportjs.org, and I came across a function in the section on custom callbacks on the authenticate page that looks almost exactly like the signin function in MEAN.JS. One difference was that it actually had some next callbacks (for error handling), so the next parameter was actually useful. Is it possible that the MEAN.JS app took a lot of code from passportjs.org's guide and changed it over time, but left in some vestigial remnants that do not do anything but were causing no harm? Or does the next parameter actually do something in passport.authenticate() that is not immediately obvious? Regardless of why this happened, does an extra next parameter in connect middleware cause any bad side effects if it is not used?
When writing middleware, the next parameter is optional. It's purpose is so that the next middleware in the chain will be called. If you want the current middleware to be the last one called for a given request, not executing the next parameter will accomplish that. This is fine for code that you write for yourself, but it's typically better to always execute the next parameter in middleware that may be used elsewhere because you don't know what else they could be adding.
For example, maybe you wanted to add some kind of logging that happens after a request is completed. If your middleware that runs before the logging middleware doesn't execute next, it won't be logged.
http://expressjs.com/api.html#middleware
Not executing next will simply not start the next middleware. There are no other side effects of not executing it other than those caused by not moving to the next middleware (for example, if the response hasn't ended yet, not calling next will result in a timeout.)

Resources