Must res.end() be called in express with node.js? - node.js

I have several Express applications, and I see that in some modules, res.end() is called at the end of a request handler (after res.send or res.json), while in others, it isn't called.
For example:
app.get('/test', function(req, res) {
res.send('Test', 200);
});
or:
app.get('/test', function(req, res) {
res.send('Test', 200);
res.end();
});
Both cases work, but I'm afraid about leaks or running out file descriptors or something like that, when I run many requests. Which one is "more correct"?

The answer to your question is no. You don't have to call res.end() if you call res.send(). res.send() calls res.end() for you.
Taken from /lib/response.js, here is the end of the res.send() function:
//. . .
// respond
this.end(head ? null : body);
return this;
}

one example where you must call end() function is when you send buffer as a file to download.
res.write(buffer);
res.end();

res.end([data] [, encoding])
Ends the response process. This method actually comes from Node core, specifically the response.end() method of http.ServerResponse.
Use to quickly end the response without any data.
If you need to respond with data, instead use methods such as
res.send() and res.json().

Related

Is there a way to make this on a single url has multiple function call?

Is there a way to make this on a single url has multiple function call? I am using express+ejs+mongo in my work.
function bla(req, res){};
function blabla(req, res){};
function blablabla(req, res){};
function renderfunc(req, res) {
res.render("index");
}
Following line works fine
app.get("/", bla, blabla, renderfunc);
but following line not works
app.get("/", bla, blabla, blablabla, renderfunc);
Only 2 functions can call in single url, then add one more function then it is not working anyway with all functions. I am not able to call three or more functions in single url.
I know this is a syntax mess, but just for giving an idea of what I would like to achieve?
Anyone know how to do this?
UPDATE:
I updated code just like this
function bla(req, res, next){
console.log("bla");
res.render("index", {orders: orders});
next();
};
function blabla(req, res, next){
console.log("blabla");
res.render("index", {jobs: jobs});
next();
};
function blablabla(req, res, next){
console.log("blablabla");
res.render("index", {foods: foods});
next();
};
app.get("/", bla, blabla, blablabla);
when i running and inside terminal showing
bla
blabla
and still not showing result of console.log("blablabla"); still third function not calling again and added req.next() is not function error occured.
How do I call function blablabla()?
If i understand right then you are trying to give multiple parameters in your link so like exemple.com/param1/param2/param3 and if that is the case you do something as so
app.get("/:param1/:param2/:param3", (req, res) =>{
var param1 = req.params.param1;
/* And declare the rest as you want it*/
});
And param1 you can change it to what ever but then when you declare it you just change it. So lets you'r parameter is a id then you can just do var ourParam= req.params.id where the parameters name is after the param
The number of function arguments is not the issue. Express allow a route to execute an unbounded number of handler functions in processing a request.
The problem here is that the path through the list of middleware functions is not being followed through to completion. This could be for a few reasons:
Any function in the chain fails to call its next (i.e., the third argument supplied to a handler function, after req and res). Because a response may depend on asynchronous operations, the completion of a function's synchronous component does not mean that next handler may execute immediately; Express will wait until the handler's code calls next to signal that the current handler has completed its work.
A function in the chain calls next with an argument (next("foo")) which halts processing of the current route (so any subsequent handler functions are never called) and begins processing the request according to the other specified route instead
Possibly one of the intermediate function finalizes the response (e.g., by calling res.redirect or res.end) so that no later function can affect the request in any way. I would expect Express to raise an error in this case (but possibly the modification could be attempted in a try block).
It sounds like you have a particular handler function that is doing one of these things, rather than having too many handler functions. The example code that you've supplied won't work at all because none of the function supplied call next, and your actual code probably has a similar problem.

Receiving 2 HTTP requests on the server when only 1 sent

I am creating an app and using http://c9.io environment to develop it. It is a NodeJS app, which provides some REST endpoints for the client side application to query. Till now, everything was running fine, and today what I observe is that for 1 call sent by the browser to the REST API, 2 requests are being shown as received, and the request handler is being called 2 times. This has slowed the response time for one request.
In Chrome developer tools, it shows only one request sent, however, I am using app.use() to log incoming requests in Express and it prints the same 2 times for each request. Also, the handler is called twice.
This is happening intermittently, not every time. I am behind a corporate network. As I have sent a lot of requests in the day for testing, is there any chance that a monitoring program is sending the requests since it finds it suspicious? I have not edited the code that handles the requests.
Edit: Adding the code for handlers as suggested.
app.get('/suggestions/:keyword', function(r, s) {
sug_db.retrieveSuggestions(r.params.keyword, function(data) {
s.writeHead(200, {'content-type': 'text/html'});
s.write(renderSugg({data: data}))
s.end();
});
});
app.get('/search/:query', function(r, s) {
esc_db.search(r.params.query, function(data) {
s.send(renderResults({query: r.params.query, results:data}));
});
});
As you can see, they do nothing but get some data from a database and return the result as HTTP response. The templating engine I am using is Pug (formerly Jade)
It doesn't look like that code that you included in the question can be guilty of running twice. But maybe some code in sug_db.retrieveSuggestions or esc_db.search does that.
What I would do is this:
Add some logging inside the code that you provided, both before calling the functions and inside the callback:
app.get('/suggestions/:keyword', function(r, s) {
console.log('*** GET /suggestions/:keyword handler');
sug_db.retrieveSuggestions(r.params.keyword, function(data) {
console.log('GET /suggestions/:keyword callback');
s.writeHead(200, {'content-type': 'text/html'});
s.write(renderSugg({data: data}))
s.end();
});
});
app.get('/search/:query', function(r, s) {
console.log('*** GET /search/:query handler');
esc_db.search(r.params.query, function(data) {
console.log('GET /search/:query callback');
s.send(renderResults({query: r.params.query, results:data}));
});
});
(or change console.log to whatever method of logging you use).
I would see what is actually called twice - the handlers themselves, or the callbacks, or none. Next would be examination of the functions that are actually called by the handlers:
sug_db.retrieveSuggestions()
esc_db.search()
renderSugg()
renderResults()
It's important to see what is actually called twice and then examine why it can be happening. But it can happen if, for example, you do something like:
function badFunction(data, callback) {
if (something) {
callback('error');
}
callback('ok');
}
instead of:
function goodFunction(data, callback) {
if (something) {
callback('error');
} else {
callback('ok');
}
}
I would expect that the functions that are called from the handlers could do something like that to call the callback twice - and maybe the condition or error that they checking didn't happen before but happens now, causing the change in behavior.

How to skip part of the middlewares that are on the stack in Express js

I am working on a backend of web application. And I have made a bunch of middlewares to be executed for each request that comes in -- [logging(before), authentication, Etag(Before), Nonce, httpRequest, Etag(after), logging(after)]. Now my problem is that, while processing each request, there are some special cases happen when the request should skip the rest of the middleware and just do logging. I can do it the dump way just make all the middleware to check if certain condition has happened and if true just call next(), and otherwise process the request using the middleware. But I am wondering if there is a clever way to do this?
Here is the snippet of the code I am currently using to configure the order of the middleware to be executed:
async.series(operations, function(err) {
if(err) {
console.log('Something blew up!!!!!!');
return next(err);
}
console.log('middleware get executed');
// no errors so pass control back to express
next();
});
Where the "operations" variable is the list of middlewares I need to execute in order. I need to use the async.series() since I need to make the order the middleware configurable. Is there a clever I can keep the order of middlewares configurable and fulfill my request as I said above?
EDIT:
An example where I need to skip the rest of the middleware is when authentication fails and write the statusCode to be "401 unauthorized", then for the stack of the middleware [logging(before), authentication, Etag(Before), Nonce, httpRequest, Etag(after), logging(after)], I will jump from authentication to logging(after). and then that would be the end of the request.
I had tried to understand your's concern
I am giving a snippet to execute middle ware function in row on the basis of need.
async.each(operations, function(operation, callback) {
if(operation) {
// if operation is required execute here
callback();
} else {
// otherwise skip just to call callback() here
callback();
}
}, function(err){
if( err ) {
console.log(err);
} else {
next();
}
});
all the operations in an array and to execute all one by one async provides .each.
Its not mandatory to call each operation. You just skip by call callback() in else condition. I want to say that in if clause you can put your mandatory execution condition.
Thanks

always run a middleware in expressjs

i want an expressjs middlware to be executed always.
That is even if there is an error in the next() or not.
is it possible?
example
app.get('/',[middle1,middle2],doIt)
the middle2 should always execute even if the middle1 executes next with error.
NOTE: the middle2 should always execute last and takes the values calculated by the previous middlewares. also there are lot of middlewares between middle1 and middle2.
If middle1 is known to not use any async operations from which it calls next(), then you can wrap it and put a try/catch around it so that if it throws, you can just call next() on its behalf.
If it does use async operations or you don't know if it will use async operations, then you will only catch its exceptions if it throws synchronously (before it goes async) and you will not be able to catch any exceptions that it throws asynchronously. About the best you could do for async behavior is to set some sort of timeout in your wrapper. If it hasn't called next() within some period of time (either because it threw an exception or just failed in some other weay), then you call next after the timeout period.
Wrapping a non-async middle1 could look like this:
function wrap(fn) {
return function(req, res, next) {
var nextCalled = false;
try {
fn(req, res, function() {
nextCalled = true;
next();
});
} finally {
if (!nextCalled) {
next();
}
}
}
}
app.get('/',[wrap(middle1),middle2],doIt);
The wrap() function inserts a stub as the middleware function. That stud inserts its own next() function so it can tell if the actual middleware function calls next() or not. It then wraps an exception handler around the middleware function so if it throws an exception synchronously, then it can recover. After the function returns, it checks to see if next() was called and, if not, it calls it.
As explained earlier this approach only works if the middleware function is synchronous.
Assuming you do not care about the order of execution, you can simply have function middle2 execute inside app.use.
app.use(middle2);
app.get('/pathx, middle1, middle3, doIt);
middle2 will always be executed on every request. However, middle2 will execute before any of the other middleware
If you require middle2 to execute last in sequence, then a simple modification using the async module should accomplish what you want
async = require('async');
function middleware(req, res, next){
var functionList = [middle1, middle3];
async.series(functionList, function(err, results){
if(err){
middle2(req, res, next);
next(err);
}
middle2(req, res, next);
next();
}
}
app.get('/pathX', middleware, doIt);

nodejs and expressjs

app.get('/', function(req, res) {
res.set('Content-Type', 'text/html');
res.send('Yo');
setTimeout(function(){
res.send("Yo");
},1000);
});
It looks like "send" ends the request. How can I get this to write Yo on the screen and then 1 second later (sort of like long polling I guess) write the other Yo to get YoYo? Is there some other method other than send?
Use res.write to generate output in pieces and then complete the response with res.end.
I don't think what you are trying to do is possible.
Once you send a response, the client-server connection will be closed.
Look into sockets (particularly socket.io) in order to keep a connection open and send multiple messages on it.
Try with JQuery+JSON. send the response and then update what ever you need with JQuery and JSON.
This is a good tutorial of expressjs, including DB stuff (mongodb).
If you want to send the result as a single block try
app.get('/', function(req, res) {
res.set('Content-Type', 'text/html');
res.write('Yo');
setTimeout(function(){
res.end("Yo");
},1000);
});
or something like
app.get('/', function(req, res) {
res.set('Content-Type', 'text/html');
var str = 'yo';
setTimeout(function(){
res.end(str + 'yo');
},1000);
});
the thing with node.js is that it relies on an asynchronous "style". so if you introduce something like a "wait" function, you'll lose all the benefits of the asynchronous way of execution.
I believe you can achieve something similar to what you want by:
(asynchronous way) including a function that prints the second "Yo" as a callback to
the first function (or)
(classic wait(synchronous) ) introduce a 'big' loop before presenting the second 'Yo'.
for example:
for(i=0; i < 100000000; i++) {
//do something
}

Resources