I am following an on-line tutorial of implementing in MEAN. Everything looks great. Except when it comes to routes. I understand that routes need to be in a javascript files (js extension). It's okay with a small web site. But as the number of requests grow, I would like to put them in separate files. I looked up in SOF for how to include files in Javascript. It is non-trivial. Has anyone faced this issue before? Can anyone comment?
Thanks
You can use Router Middleware by using express.Router(). This allows you to break your routes into different files. On a side note, middleware is very powerful and is worth learning about, its a huge part of Express.
Say you have an app that has a /users section. You can create a separate routes file called users.js that contains all routes that pertain to your /users resources. Then inside your server.js where your main Express app is listening, you can assign the users.js routes to the /users resource using app.use().
You can have as many routers as you'd like, all routes are read top-down when Express is deciding which route to use.
./routes/users.js
// Create an express router
var router = require('express').Router();
// Define a route for GET /
router.get('/', function(req, res) {
res.status(200).send('Welcome to /users');
});
// make our router available for require() statements
module.exports = router;
server.js
var express = require('express');
var app = express();
// Users routes
var users = require('./routes/users');
// Tell our app to use the Users routes defined in ./routes/users.js
app.use('/users', users);
app.listen(process.env.PORT || 3000, function() {
console.log('listening');
});
Is there a way to run middleware on all express routes except for static assets?
I tried running it right in the app.use('/', authenticate, app.router()); but that leads to it running for all static assets as well.
Would I just have to list it on all my routes?
As #Explosion Pills points out in the comments,
add your middleware after the express.static middleware
Sample codes as below
app.use('/', express.static(path.resolve(root, './build/client')));
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true});
// ...
app.use('/', authenticate, app.router());
Since I am new to Express 4, I will try to make my question as simple as possible.
I have been referring to some online tutorials and a confusion has raised.
Normally, the Express 4 setup for app.js has the following type of routes code
.
.
.
var routes = require('./routes/index');
var users = require('./routes/users');
.
.
.
app.use('/', routes);
app.use('/users', users);
I use either Get or Post with whatever parameters, the above works perfect.
However, in another tutorial, I see it done differently -like this
.
.
.
var routes = require('./routes’);
.
.
.
app.get('/', routes.index);
app.get('/login', routes.user.login);
.
.
.
I am confused, because normally, I use the app.get method inside the /routes/index.js file OR for anything user related, I use the app.get method in /routes/users.js
Why do we use the app.get directly in the app.js file rather then in the /routes/user.js or /routes/index.js files. Is there any special purpose for doing it this way?
Any help would be highly appreciated.
Thanks, in advance.
We all have specific ways that we like to do things. I say this is one of that situations. Only special purpose that I can think of for these types is that some implementations are more suitable for some scenarios.
Example that I have given below is another way of implementing this. I completely move all codes related to routes to another file because I do not need to access router in the app.js
If I want to access router in the app.js, I would have used one of the above implementations.
//We can pass both app, express or just app based on our requirements.
//app.js
require('./app/routes.js')(app, express);
//app/routes.js
module.exports = function(app, express) {
var router = express.Router();
router.route('/users')
.get(function(req,res){
//......
});
app.use('/', router);
};
I hope you got my point.
Why would I do:
var router = express.Router();
router.get('/', ...)
instead of
app.get('/', ...);
The two will give me the same result. What's the point of instantiating a router if app is already a router?
It's useful if you're writing a very complex app. For example, you might have a tree like this:
routes
user.js
post.js
server.js
In both user.js and post.js, you would create a Router object and export it. You can attach all the routes for the user to that router - say /user/new, /user/edit, and /user/1, and /post/new, /post/edit, and /post/1.
In server.js, you would require each of your routes and attach their routers via app.use:
app.use('/user', user);
app.use('/post', post);
All requests to /user will then be sent to the user router, and all requests to /post will be sent to the post router. Then, you can register routes like:
router.get('/new', function(req, res) { });
And it will automatically be mapped to /user/new or /post/new. This is useful because it helps organize your app, and it forces you to segregate one section of your application into one file (separation of concerns and all that). It's a useful part of express that isn't very well advertised.
Revisiting the router middleware
The router middleware is very special middleware. While other Express
middlewares are inherited from Connect, router is implemented by
Express itself. This middleware is solely responsible for empowering
Express with Sinatra-like routes.
The router middleware is a middleware system of its own. The route
definitions form the middlewares in this stack. Meaning, a matching
route can respond with an HTTP response and end the request flow, or
pass on the request to the next middleware in line.
and then
To ensure predictability and stability, we should explicitly add
router to the middleware stack
app.use(app.router);
Before I ask about app.router I think I should explain at least what I think happens when working with middleware. To use middleware, the function to use is app.use(). When the middleware is being executed, it will either call the next middleware by using next() or make it so no more middleware get called. That means that the order in which I place my middleware calls is important, because some middleware depends on other middleware, and some middleware near the end might not even be called.
Today I was working on my application and had my server running in the background. I wanted to make some changes and refresh my page and see the changes immediately. Specifically, I was making changes to my layout. I couldn't get it to work so I searched Stack Overflow for the answer and found this question. It says to make sure that express.static() is beneath require('stylus'). But when I was looking at that OP's code, I saw that he had his app.router call at the very end of his middleware calls, and I tried to figure out why that was.
When I made my Express.js application (version 3.0.0rc4), I used the command express app --sessions --css stylus and in my app.js file the code came setup with my app.router above both the express.static() and require('stylus') calls. So it seems like, if it comes already setup that way, then it should stay that way.
After re-arranging my code so I could see my Stylus changes, it looks like this:
app.configure(function(){
//app.set() calls
//app.use() calls
//...
app.use(app.router);
app.use(require('stylus').middleware(__dirname + '/public'));
app.use(express.static(__dirname + '/public', {maxAge: 31557600000}));
});
app.get('/', routes.index);
app.get('/test', function(req, res){
res.send('Test');
});
So I decided that the first step would be to find out why it is important to even have app.router in my code. So I commented it out, started my app and navigated to /. It displayed my index page just fine. Hmm, maybe it worked because I was exporting the routing from my routes file (routes.index). So next I navigated to /test and it displayed Test on the screen. Haha, OK, I have no idea what app.router does. Whether it is included in my code or not, my routing is fine. So I am definitely missing something.
So Here Is My Question:
Could somebody please explain what app.router does, the importance of it, and where I should place it in my middleware calls? It would also be nice if I got a brief explanation about express.static(). As far as I can tell, express.static() is a cache of my information, and if the application can't find the requested page, it will check the cache to see if it exists.
Note: This describes how Express worked in versions 2 and 3. See the end of this post for information about Express 4.
static simply serves files (static resources) from disk. You give it a path (sometimes called the mount point), and it serves the files in that folder.
For example, express.static('/var/www') would serve the files in that folder. So a request to your Node server for http://server/file.html would serve /var/www/file.html.
router is code that runs your routes. When you do app.get('/user', function(req, res) { ... });, it is the router that actually invokes the callback function to process the request.
The order that you pass things to app.use determines the order in which each middleware is given the opportunity to process a request. For example, if you have a file called test.html in your static folder and a route:
app.get('/test.html', function(req, res) {
res.send('Hello from route handler');
});
Which one gets sent to a client requesting http://server/test.html? Whichever middleware is given to use first.
If you do this:
app.use(express.static(__dirname + '/public'));
app.use(app.router);
Then the file on disk is served.
If you do it the other way,
app.use(app.router);
app.use(express.static(__dirname + '/public'));
Then the route handler gets the request, and "Hello from route handler" gets sent to the browser.
Usually, you want to put the router above the static middleware so that a accidentally-named file can't override one of your routes.
Note that if you don't explicitly use the router, it is implicitly added by Express at the point you define a route (which is why your routes still worked even though you commented out app.use(app.router)).
A commenter has brought up another point about the order of static and router that I hadn't addressed: the impact on your app's overall performance.
Another reason to use router above static is to optimize performance. If you put static first, then you'll hit the hard drive on every single request to see whether or not a file exists. In a quick test, I found that this overhead amounted to ~1ms on an unloaded server. (That number is much likely to be higher under load, where requests will compete for disk access.)
With router first, a request matching a route never has to hit the disk, saving precious milliseconds.
Of course, there are ways to mitigate static's overhead.
The best option is to put all of your static resources under a specific folder. (IE /static) You can then mount static to that path so that it only runs when the path starts with /static:
app.use('/static', express.static(__dirname + '/static'));
In this situation, you'd put this above router. This avoids processing other middleware/the router if a file is present, but to be honest, I doubt you'll gain that much.
You could also use staticCache, which caches static resources in-memory so that you don't have to hit the disk for commonly requested files. (Warning: staticCache will apparently be removed in the future.)
However, I don't think staticCache caches negative answers (when a file does not exist), so it doesn't help if you've put staticCache above router without mounting it to a path.
As with all questions about performance, measure and benchmark your real-world app (under load) to see where the bottlenecks really are.
Express 4
Express 4.0 removes app.router. All middleware (app.use) and routes (app.get et al) are now processed in precisely the order in which they are added.
In other words:
All routing methods will be added in the order in which they appear. You should not do app.use(app.router). This eliminates the most common issue with Express.
In other words, mixing app.use() and app[VERB]() will work exactly in the order in which they are called.
app.get('/', home);
app.use('/public', require('st')(process.cwd()));
app.get('/users', users.list);
app.post('/users', users.create);
Read more about changes in Express 4.
Routing means determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on).
Each route can have one or more handler functions, which are executed when the route is matched.
In Express 4.0 Router, we are given more flexibility than ever before in defining our routes.
express.Router() is use multiple times to define groups of routes.
route used as middleware to process requests.
route used as middleware to validate parameters using ".param()".
app.route() used as a shortcut to the Router to define multiple requests on a route
when we are using app.route(), we are attaching our app with that router.
var express = require('express'); //used as middleware
var app = express(); //instance of express.
app.use(app.router);
app.use(express.static(__dirname + '/public')); //All Static like [css,js,images] files are coming from public folder
app.set('views',__dirname + '/views'); //To set Views
app.set('view engine', 'ejs'); //sets View-Engine as ejs
app.engine('html', require('ejs').renderFile); //actually rendering HTML files through EJS.
app.get('/', function (req, res) {
res.render('index');
})
app.get('/test', function (req, res) {
res.send('test')
})
In express Version 4 we can easily define routes in the following manner:
server.js:
const express = require('express');
const app = express();
const route = require('./route');
app.use('/route', route);
// here we pass in the imported route object
app.listen(3000, () => console.log('Example app listening on port 3000!'));
route.js:
const express = require('express');
const router = express.Router();
router.get('/specialRoute', function (req, res, next) {
// route is now http://localhost:3000/route/specialRoute
});
router.get('/', function (req, res, next) {
// route is now http://localhost:3000/route
});
module.exports = router;
In server.js we imported the router object of the route.js file and apply it in the following manner in server.js:
app.use('/route', route);
Now all of the routes in the route.js have the following base URL:
http://localhost:3000/route
Why this approach:
The main advantage of taking this approach is that now our app is more modular. All the route handlers for a certain route now can be put into different files which makes everything more maintainable and easier to find.
An article by #kelyvinn from 2016, with the intent to demonstrate modularity, includes this code:
// controllers/apis/dogs/index.js
const
express = require('express'),
dogService = require('../../../services/dogs');
let router = express.Router();
router.get('/', dogService.getDogs);
router.get('/:id', dogService.getDogWithId);
module.exports = router;