ElvisKang
ElvisKang

Reputation: 77

Is there a required order for middleware declaration in Express?

I found that if middleware in app.js were in the wrong order , they wouldn't work well.

For example:

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');  //
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());  //
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);
//the codes below don't work 
//set Cookie
app.use(cookieParser());
app.use(session({
    secret:setting.cookieSecret,
    key: setting.db,
    cookie:{maxAge:1000*3600*24*30},
    store: new MongoStore({db:setting.db}),
    saveUninitialized: true,
    resave: true
}) );
//use 'connect-flash'
app.use(flash());      

If the code app.use(flash()) isn't moved after app.set('view engine', 'ejs');, the page will show TypeError: Object #<IncomingMessage> has no method 'flash'.

What's more,if I just move app.use(flash()) it creates the error req.flash() requires sessions but the error goes away if I move cookieParse() and session() to follow urlencoded().

Editing the first code example to this no longer creates errors:

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
//changed
app.use(flash());
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
//changed
app.use(cookieParser());
app.use(session({
    secret:setting.cookieSecret,
    key: setting.db,
    cookie:{maxAge:1000*3600*24*30},
    store: new MongoStore({db:setting.db}),
    saveUninitialized: true,
    resave: true
}) );

app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

So I want to know : Is there a mandatory order that the middleware and configuration in app.js must follow?

Upvotes: 1

Views: 753

Answers (1)

Matthew Bakaitis
Matthew Bakaitis

Reputation: 11990

Yes. The order you call middleware or configuration in Express is important. From the express api docs:

The order of which middleware are "defined" using app.use() is very important, they are invoked sequentially, thus this defines middleware precedence.

This is why you get the different errors as you move the different app.use lines around.

For example, if you are using connect-flash for your flash() function, connect-flash requires both cookieparser and session middleware to be loaded first. There is an order dependency -- cookieparser, then session, then flash.

Order is also important for routing. See the New features in Express 4.x and this stackoverflow answer for details and discussion.

Therefore, when using express, check the documentation to be sure you meet order-based dependencies for middleware and routes (when applicable).

Upvotes: 2

Related Questions