What is the difference between "express.Router" and routing using "app.get"? - node.js

I have an app with following code for routing:
var router = express.Router();
router.post('/routepath', function(req, res) {});
Now I have to put routing code in different files so I tried to use this approach, but it is not working perhaps because instead of express.Router() it uses:
app.post("/routepath", function (req, res) {});
How can I put routing in different files using express.Router()?
Why app.get, app.post, app.delete, etc, are not working in app.js after using express.Router() in them?

Here's a simple example:
// myroutes.js
var router = require('express').Router();
router.get('/', function(req, res) {
res.send('Hello from the custom router!');
});
module.exports = router;
// main.js
var app = require('express')();
app.use('/routepath', require('./myroutes'));
app.get('/', function(req, res) {
res.send('Hello from the root path!');
});
Here, app.use() is mounting the Router instance at /routepath, so that any routes added to the Router instance will be relative to /routepath.

Related

Cannot enter router get in express

I am trying to use routers in my Node js application. I cannot execute router.get functiom
In the main file which is server.js I used this script
// Routes
app.use('/api/v1/stores', require('./routes/stores'));
But in the route file which is stores.js, I cannot enter the router.get function and execute it
const express = require('express');
const router = express.Router();
console.log("I can reach this point")
router.get('/', (req, res) => {
console.log("I can not reach this point")
res.send('app/about');
});
module.exports = router;
That's because new express version 4.17.* is different when handling routes. try,
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('app/about');
});
module.exports = app;
For more details: https://expressjs.com/en/guide/routing.html
you can try this way also, in your store.js file create something like this.
module.exports = app => {
app.get('/', (req, res) => {
res.send('app/about');
});
}
and add this require to server.js
require('./store')(app);

Why express.Router() while separating routes

I have gone through express document in that i have learn about
Router() and express.Router(). so my question is i have separated
my all routes from main app and created different folder there i did
not create any router object(var router express.Router()) for
routing to specific path still it's working fine. So i want to know
why this Router class is necessary ?
see, This is main app file,
'use strict'; const startUpDebugger=require('debug')('app:startUp');
const dbDebugger=require('debug')('app:db'); const express =
require('express'); const app = express(); const
moragan=require('morgan'); const helmet=require('helmet'); const
config=require('config'); const courses=require('./routes/courses');
const home=require('./routes/home'); app.use(helmet());
app.set('view engine','pug'); app.set('views','./view');
app.use(express.json()); app.use('/api/courses',courses);
app.use('/',home);
console.log(Node enironment variable: ${process.env.NODE_ENV});
console.log(Application name : ${config.get('name')});
console.log(mail server : ${config.get('mail.host')});
if(app.get('env')==='development'){
app.use(moragan('tiny'));
startUpDebugger("******Morgan enabled*******") }
const port = process.env.PORT || 5000; app.listen(port);
console.log(Api Node running on port ${port});
This is my courses.js which is my route file
const express=require('express'); const app=express
const courses=[{"id":1,"course":"course1"},
{"id":2,"course":"course2"},
{"id":3,"course":"course3"},
{"id":4,"course":"course4"}]
app.route('/posting').post((req,res)=>{
console.log(req.body);
courses.push(req.body)
res.status(201).send(courses); }).put((req,res)=>{
res.send("Successfully put message") }) app.get('/sub/:id',(req,res)=>{
res.status(200).send(req.params); })
module.exports=app;
your question is not clear but if i am getting you right:-
If your app is really simple, you don't need routers.
//you can just invoke express constructor and use it
const app=express()
app.get('/', function (req, res) {
res.send('root')
}) // app.get,app.post and so on
in your main app file.
But as soon as it starts growing, you'll want to separate it into smaller "mini-apps", so that it's easier to test and maintain, and to add stuff to it. You'll avoid a huge main app file :) .
so here you need to make another file for routes and have to invoke express.Router() class and use it
like:
//route.js
const Router=express.Router()
// middleware that is specific to this router
router.use(function timeLog (req, res, next) {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', function (req, res) {
res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
res.send('About birds')
})
And import this file into the main app file and pass it to middleware to use
app.use('/',require('./routes/routes.js'))
and comparing to express() object the express.Router() object is light weight

Nodejs Express router.get('/') in users.js

I m still trying to learn NodeJs but I came across this path thing I encountered in Express. When I create an app using Express I noticed that in app.js I have these lines of code var index = require('./routes/index');
var users = require('./routes/users');
app.use('/', index);
app.use('/users', users);
And in users.js I already have configured
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
I don t really understand why is it in users.js router.get('/') instead of router.get('/users') as it is specified in app.js? Can someone explain a bit what s going on in this case?
As far as I understand in app.js it says whenever someone tries to access the specified route('/users') lets say localhost:3000/users in the browser, let the file required in users variable handle it.
If you are working with routes the express app is automatically . Here is an example from the express.js website:
In our router file we have:
var express = require('express')
var router = express.Router()
// middleware that is specific to this router
router.use(function timeLog (req, res, next) {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', function (req, res) {
res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
res.send('About birds')
})
module.exports = router
Then in our main file were we have our server etc we load in the router:
var birds = require('./birds')
// ...
app.use('/birds', birds)
These routes in the router app are only accessed when there is a request to to /birds url. All the routes in the router are now automatically staring with /birds
So this code in the express router:
// im code in the birds router
router.get('/about', function (req, res) {
res.send('About birds')
})
Is only executed when someone makes a get request to the /birds/about url.
More information in the official express.js docs
I would just like to point out what I have learnt today after some frustration, and maybe somebody can elaborate as to why this happens. Anyway, if, like me, you want to use '/users' for all user routes or '/admin' for all administrator routes then, as WillemvanderVeen mentioned above, you need to add the following code to your main app.js file
var users = require('./routes/users')
app.use('/users', users)
However, one thing which was not mentioned is that the order with which you declare your 'app.use('/users', users)' in app.js is important. For example, you would have two route handling files as so:
/routes/index.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => { res.render('index') });
/routes/users.js
const express = require('express'); const router = express.Router();
router.get('/', (req, res) => { res.send('users route') })
You would then require them in your main app.js file as so:
app.js
const express = require('express');
const app = express();
const index = require('./routes/index');
const users = require('./routes/users');
app.use('/', index);
app.use('/users', users);
and you would expect that when you hit the '/users' route that you would receive the res.send('users route') page.
This did not work for me, and I struggled to find any solution until recently, which is why I am now commenting to help you.
Instead, I swapped the app.use() declarations in app.js around like so and it worked:
app.js
const express = require('express');
const app = express();
const index = require('./routes/index');
const users = require('./routes/users');
app.use('/users', users);
app.use('/', index);
Now when I hit '/users' I see the 'users route' message. Hope this helped.
To answer your question though, when you configure the route handler in app.js as users, then you are requiring a router file (./routes/users) to handle all requests from that file and sending them to the URL /users first. So if you do the following:
/routes/users.js
router.get('/dashboard', (req, res) => {
// get user data based on id and render it
res.render('dashboard')
});
then whenever user is logged in and goes to dashboard, the URL will be /users/dashboard.

custom express.js mounting does not work

I have trouble implementing route mounting in express.js 4.13.3.
When I first install it, by default created in the app.js
var users = require('./routes/users');//get the "users" route
app.use('/users', users);//mount to "/users"
and the users.js route is like
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.send('respond with a resource');
});
module.exports = router;
Does not need to define router.get('/users'... because mounting took care of that in the app.js file.
But
When I try to do the same thing
in app.js I set
var upload = require('./routes/upload');
app.get('/upload', upload);//mounting (?)
the upload.js route is
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('upload', {title: 'Photo upload'});
});
module.exports = router;
When I access localhost/users I get 404 error. The only way to fix this , is to define in the upload.js router, this router.get('/upload' instead of this router.get('/'. But that would not be mounting.
The difference I see is that the default code uses app.use('/users', users); and my code uses app.get('/upload', upload);. Is the verb (use/get) the only difference that causes the 404? And if so, why? Or is it something else?
Thanks
You are totally correct that the problem is caused because these to functions work differently. Below are the official API specifications for the functions.
app.use is for mounting a middleware
app.get is for defining (only) one route for a HTTP GET request
This example shows a middleware function mounted on the /user/:id path. The function is executed for any type of HTTP request on the /user/:id path.
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
This example shows a route and its handler function (middleware system). The function handles GET requests to the /user/:id path.
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});

Express 4 router

At this point, I am pretty clear on how the Express 4 router works, but I am confused about how the primary router instance declared in the app.js file, like it is immediately below, interacts with other routers in the Express server.
so you start off with this in your app.js file:
var express = require('express');
var router = express.Router();
var app = express();
in your Express 4 app.js file you will then do:
app.use(router); //what is this doing? maybe nothing
then you might do (in the same file app.js):
var loginRoute = require('../routes/login');
var logoutRoute = require('../routes/logout');
app.use('/login',loginRoute);
app.use('/logout',logoutRoute);
and inside loginRoute we have
var express = require('express');
var router = express.Router();
router.get('/',function(req,res,next){
}
router.post('/',function(req,res,next){
}
and in logoutRoute we might have pretty much the same skeleton as loginRoute:
var express = require('express');
var router = express.Router();
router.get('/',function(req,res,next){
}
router.post('/',function(req,res,next){
}
I am warming up to this new router for Express 4, but I still am in the dark about how it works. So my question is, how does the Express router in app.js interact with the other routers?
and what exactly does the line app.use(require('express').Router()) supposed to be doing? My guess is that calling app.use(router); tells Express 4 about your intentions - your intention to use that router instead of the single basic router for app.
But given the code, I don't see how app.use(router) interacts or has anything to do with the routers used by app.use('/login'..) and app.use('/logout'..).
Can Express 4 routers delegate to each other? Can you give an example of this?
I hope your understand my confusion.
One way to think about routers in Express 4+ is as micro-services that can be mounted on either the app itself or on other routers.
For example when mounting on the app itself:
var routerA = express.Router();
var routerB = express.Router();
routerA
.post('/bar', function (req, res, next) {...})
.get('/bar', function (req, res, next) {...});
routerB
.post('/bar', function (req, res, next) {...})
.get('/bar', function (req, res, next) {...});
// Mount routerA at `/foo`
// handles both get and post requests to /foo/bar but not /bar/bar
app.use('/foo', routerA);
// Mount routerB at `/bar`
// handles both get and post requests to /bar/bar but not /foo/bar
app.use('/bar', routerB);
And if you wanted to mount one router to another:
var routerA = express.Router();
var routerB = express.Router();
routerA
.post('/bar', function (req, res, next) {...})
.get('/bar', function (req, res, next) {...});
routerB
.post('/bar', function (req, res, next) {...})
.get('/bar', function (req, res, next) {...});
// Mount routerB to routerA at `/foo`
// handles both get and post requests to /foo/bar at routerA's mount point
routerA.use('/foo', routerB);
// Mount routerA at `/foobar`
// handles both get and post requests to /foobar/bar with routerA
// and /foobar/foo/bar with routerB
app.use('/foobar', routerA);
Using routers in this way can make your code a bit more modular while also allowing for things like this.
Regarding the use of app.use(router) without anything assigned to that router: it's useless. You could remove it without an impact to the application. The routers that are mounted after are the ones actually doing the routing.

Resources