app.use(express.static()) at the end of the program - javascript

As far as I understand when I use app.use(middleware) this middleware will be called on every request on a server.
So when I use express.static() as a middleware it will to be called on every request too but in this case it's not needed to be called on any request so why do I need to put it at the top of my program? I haven't seen anybody puts it before app.listen(). Why is this so?
Does it cause any performance degradation?

You need to have in mind the middleware works as a pipe, so, all middleware will be executed in the same order you add them.
E.G.
If you have installed the express JSON middleware, the static middleware and an authorization middleware (in this order), and your endpoint the flow of a request will be:
/ Server \
Client -----> | json -> static -> authorization -> endpoint -> EGEH |
\ /
Note: EGEH stands for Express Global Error Handler.
But if some of those elements send a response or throw an error (caught by the EGEH) the flow must be different.
In general, if you know your statics would be the last option, you could use it at the end (after the server.listen or whatever), and that would not affect the behavior, however, if that is the case may be a better option is to use the server engine (Nginx, Apache, etc) to dispatch those files to the customer instead of make node spend CPU to do that.

Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. The next middleware function is commonly denoted by a variable named next
So that's why express static usually go first

Related

Why does an Express function take both the Request and Response as arguments?

I am new to node.js and am acquainting myself with Express. The following code is my source of confusion:
var server = http.createServer(handleRequest);
function handleRequest(req, res) {
var path = req.url;
switch (path) {
case "/n":
return renderPage_1(req, res);
default:
return renderPage_2(req, res);
}
}
I understand that the server needs to accept an HTTP request(req). However, if we are returning a response, why is the response also an argument in the callback function? I keep running into a dead-end thinking that it has to do with the scope of the response object, though I am not sure.
I would greatly appreciate clarification on this matter. I have not been able to find a resource that delineates my confusion.
Best,
Abid
I think the answer to your question is that this is how the authors of express decided to implement the library. At a high level, express is really just a light-ish weight wrapper that makes it easy to build middleware based http services with NodeJS. The reason that both the req & res objects are passed to each express middleware function is that in practice, web services are rarely able to fulfill an entire request in a single step. Often services are built as layer of middleware the build up a response in multiple steps.
For example, you might have a middleware function that looks for identity information in the request and fetches any relevant identity metadata while setting some auth specific headers on the response. The request might then flow to an authorization middleware that uses the fetched metadata to determine if the current user is authorized and if the user is not authorized can end the request early by closing the response stream. If the user is authorized then the request will continue to the next piece of middleware etc. To make this work, each middleware function (step of the stack) needs to be able to access information from the request as well as write information to the response. Express handles this by passing the request and response objects as arguments to the middleware function but this is just one way to do it.
Now the authors could have decided to implement the library differently such that each route handler was supposed to return an object such as { status: 200, content: "Hello, world" } instead of calling methods on the response object but this would be a matter of convention and you could pretty easily write a wrapper around express that let you write your services like this if you wanted.
Hope this helps.

How to bypass an express middleware?

I'm working with an express application. There are some express routes, as
server.get('*' , ... )
etc. which perform some common operations: authentication, validation... etc.
they also decorates the response with meaningful information: i.e. in every request to the server it gives not only the expected json/html, but also information regarding the user, some app metadata that the front-end consumes etc. etc.
Let's say all this extra metadata cames in a field called extradata in every request to the server.
Now, there is a bug that is causing a problem: instead of returning its expected response (a json with a bunch of system logs), is sending only this extradata field.
I'm pretty confident the problem is in one of the middlewares, because that code that sends the response in this case is really simple, it's just a res.send() of a json. So I believe this part of the app is requiring some module that sets a middleware which causes the error. There are a lot of global vars and implicit parameters in the app so is really difficult to debug it manualluy.
I attempted to bypass such middlewares programmatically, like:
delete server._router.stack[2];
but is causing an TypeError: Cannot read property 'route' of undefined and thus preventing my app to build: sure this is not the way to go.
so, is there a way to programmatically ignore or bypass express routes that are yet set?
Even better, is there a way to programmatically tap into express middlewares and log every request and response?
(afaik, there are libreries like morgan that logs every request, but I don't think they apply to this case since I need to discriminate between middlewares).
What I generally do is simply use the next method. You can access it by simply passing it to the callback function. Something like:
app.use(function(req, res, next) {
if(...) {
next();
} else {
...
}
}
What this is going to do is go to the next middleware.
So if I understand correctly, you can check what you exactly need in the if-statement and do things accordingly.
What I would suggest is you read the Express API documentation, especially the section about middleware, which you can find here. Moreover, try to isolate the suspects and solve the issue by removing the problem, rather than deleting handlers and trying to solve the problem the easy way.

Express sometimes picking wrong route

I am having a NodeJS based REST service exposed using Express (4.0.0) where I have two different routes like this:
router.get('/buckets/:bucketId/entities/bulk', getEntitiesInBulk);
router.get('/buckets/:bucketId/entities/:key', getEntityByKey);
When I send a request like this:
http://<server:port>/buckets/responses/entities/k3
The request is being handled by getEntityByKey() which I have defined there, but strangely when I bombard it with many requests it sometimes get handled by getEntitiesInBulk() and gets some error in response which is only thrown by getEntitiesInBulk().
I am totally confused about how is this possible.
Express is confused because your routes are not unique. "bulk" will sometimes be used as a :key in the first route. Simply change the signature a bit, like
router.get('/buckets/:bucketId/entities/bulk', getEntitiesInBulk);
router.get('/buckets/:bucketId/entity/:key', getEntityByKey);

Global server session in express node.js app

How should I gave access to the current session to the modules of my node.js app considering that I can only get it inside the request's function?
It's a fairly complex but modular app and passing the session around seems a bit difficult, and I would have to reimplement a lot of things.
Ideally i would attach it to an object exported with module.exports and require it in other modules. But I'm afraid that on concurrent requests it would get overwritten and I could end up with conflicts.
Have you tried res.locals ?
In the Official Docs, it says "Response local variables are scoped to the request, thus only available to the view(s) rendered during that request / response cycle, if any. This object is useful for exposing request-level information such as the request pathname, authenticated user, user settings etcetera. "
When your middleware/route callback is called, you can define res.locals.myProp = "some value" and access it from a view, using locals.myProp.
I solved this by using express-domain-middleware which binds incoming request & response from express to a new domain.

Node.js Programming Pattern for getting Execution Context

I am writing a web app in node.js. Now every processing on the server is always in the context of a session which is either retrieved or created at the very first stage when the request hits the server. After this the execution flows through multiple modules and callbacks within them. What I am struggling with is in creating a programming pattern so that at any point in the code the session object is available without the programmer requiring it to pass it as an argument in each function call.
If all of the code was in one single file I could have had a closure but if there are function calls to other modules in other files how do I program so that the session object is available in the called function without passing it as an argument. I feel there should be some link between the two functions in the two files but how to arrange that is where I am getting stuck.
In general I would like to say there is always a execution context which could be a session or a network request whose processing is spread across multiple files and the execution context object is to be made available at all points. There can actually be multiple use cases like having one Log object for each network request or one Log object per session. And the plumbing required to make this work should be fitted sideways without the application programmer bothering about it. He just knows that that execution context is available at all places.
I think it should fairly common problem faced by everyone so please give me some ideas.
Following is the problem
MainServer.js
app = require('express').createServer();
app_module1 = require('AppModule1');
var session = get_session();
app.get('/my/page', app_module1.func1);
AppModule1.js
app_module2 = require('AppModule2');
exports.func1 = function(req,res){
// I want to know which the session context this code is running for
app_module2.func2(req,res);
}
AppModule2.js
exports.func2 = function(req,res){
// I want to know where the session context in which this code is running
}
You can achieve this using Domains -- a new node 0.8 feature. The idea is to run each request in it's own domain, providing a space for per-request data. You can get to the current request's domain without having to pass it all over via process.domain.
Here is an example of getting it setup to work with express:
How to use Node.js 0.8.x domains with express?
Note that domains in general are somewhat experimental and process.domain in particular is undocumented (though apparently not going away in 0.8 and there is some discussion on making it permanent). I suggest following their recommendation and adding an app-specific property to process.domain.data.
https://github.com/joyent/node/issues/3733
https://groups.google.com/d/msg/nodejs-dev/gBpJeQr0fWM/-y7fzzRMYBcJ
Since you are using Express, you can get session attached to every request. The implementation is following:
var express = require('express');
var app = express.createServer();
app.configure('development', function() {
app.use(express.cookieParser());
app.use(express.session({secret: 'foo', key: 'express.sid'}));
});
Then upon every request, you can access session like this:
app.get('/your/path', function(req, res) {
console.log(req.session);
});
I assume you want to have some kind of unique identifier for every session so that you can trace its context. SessionID can be found in the 'express.sid' cookie that we are setting for each session.
app.get('/your/path', function(req, res) {
console.log(req.cookies['express.sid']);
});
So basically, you don't have to do anything else but add cookie parser and enable sessions for your express app and then when you pass the request to these functions, you can recognize the session ID. You MUST pass the request though, you cannot build a system where it just knows the session because you are writing a server and session is available upon request.
What express does, and the common practice for building an http stack on node.js is use http middleware to "enhance" or add functionality to the request and response objects coming into the callback from your server. It's very simple and straight-forward.
module.exports = function(req, res, next) {
req.session = require('my-session-lib');
next();
};
req and res are automatically passed into your handler, and from their you'll need to keep them available to the appropriate layers of your architecture. In your example, it's available like so:
AppModule2.js
exports.func2 = function(req,res){
// I want to know where the session context in which this code is running
req.session; // <== right here
}
Nodetime is a profiling tool that does internally what you're trying to do. It provides a function that instruments your code in such a way that calls resulting from a particular HTTP request are associated with that request. For example, it understands how much time a request spent in Mongo, Redis or MySQL. Take a look at the video on the site to see what I mean http://vimeo.com/39524802.
The library adds probes to various modules. However, I have not been able to see how exactly the context (url) is passed between them. Hopefully someone can figure this out and post an explanation.
EDIT: Sorry, I think this was a red-herring. Nodetime is using the stack trace to associate calls with one another. The results it presents are aggregates across potentially many calls to the same URL, so this is not a solution for OP's problem.

Categories