Using multiple router in express - node.js

I've applied the routes to my application like this:
var express = require('express');
var app = express();
var router = express.Router();
//localhost:8080/api/story
router.get('/story', function(req, res){
res.send('welcome to our story');
})
//localhost:8080/api
app.use('/api', router);
//localhost:8080/user/02213
router.get('/user/:id', function(req , res){
console.log(req.params.id);
});
localhost:8080/user/02213 not working at the moment. Do I need to create a new router instead or?

Yes, you need to create a new router, because router will only be used for requests that start with /api:
//localhost:8080/api/story
router.get('/story', function(req, res){
res.send('welcome to our story');
})
//localhost:8080/api
app.use('/api', router);
//localhost:8080/user/02213
var anotherRouter = express.Router();
anotherRouter.get('/user/:id', function(req , res){
console.log(req.params.id);
res.end();
});
app.use('/', anotherRouter);

The problem is that id not recognized in the request,
You should call it like that : req.params.id

Related

getting a type Error when running file on node

I'm new to node and express, was trying to test some basics routes but getting a Type Error: Router.use() requires a middle ware function but got an object
This is what I have in app.js
const express = require('express');
const routes = require('./routes/api');
// set up express app
const app = express();
app.use('/api', routes);
//listen for request
app.listen(process.env.port || 4000, function(){
console.log('now listening for requests');
});
and in my api.js:
const express = require('express');
//store router object to a vairable to enable us use routes on api.js
const router = express.Router();
router.get('/ninja', function(req, res){
res.send('{type: "GET"}');
})
router.post('/ninja', function(req, res){
res.send({type: "POST"});
})
//to update an api, where id is a parameter.
router.put('/ninja/:id', function(req, res){
res.send({type: "PUT"});
})
//to delete an api
router.get('/ninja/:id', function(req, res){
res.send({type: "DELETE"});
})
module.exports = router;
I have tried exporting router on each file, none worked.

Node.js and express : Routes

I have some trouble using the router from Express.
I want to set up my routes with several files.
I get my routes folder with 2 files: routes.js and inscription.js
I do the following
var inscription = require('./routes/inscription.js');
var routes = require('./routes/routes.js');
Then
app.use('/', routes);
app.use('/inscription', inscription);
But only the routes from routes.js work...
This is the content of routes.js
var router = require('express').Router();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false});
//Homepage
router.get('/', function(req, res){
res.setHeader('Content-Type', 'text/html');
res.status(200);
res.render('home.ejs');
});
//Connexion
router.post('/connexion', urlencodedParser, function(req, res){
//Some content
});
module.exports = router;
And this is the content of inscription.js
var router = require('express').Router();
var hash = require('password-hash');
var db = require('../models/users.js');
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false});
router.get('/inscription', function(req, res){
res.setHeader('Content-Type', 'text/html');
res.status(200);
res.render('inscription.ejs');
});
router.post('/adduser', urlencodedParser, function(req, res){
var passwordHashed = hash.generate(req.body.inputPassword);
var newUser = {
nom : req.body.inputName,
email : req.body.inputEmail,
password : passwordHashed
};
db.addUser(newUser);
res.redirect('/');
});
router.post('/checkname', urlencodedParser, function(req, res){
var user = {
nom : req.body.inputName
};
db.checkName(user, function(length){
res.send(length);
});
});
router.post('/checkemail', urlencodedParser, function(req, res){
var user = {
email : req.body.inputEmail
};
db.checkEmail(user, function(length){
res.send(length);
});
});
module.exports = router;
The content of inscription.js works when it is pasted in the routes.js file ...
So I guess it is how I import the file that is not working.
Any idea?
This route router.get('/inscription', ...) in your inscription router is configured for the route /inscription/inscription which is likely not what you intended. This is because you've specified it in two places:
app.use('/inscription', inscription);
router.get('/inscription', ...)
So, the whole router is on /inscription from the app.use('/inscription', inscription). That means that any route the router itself defines will be added to that path.
It isn't exactly clear from your question exactly what you intend for the URLs to be. But, if you just want the above router.get() to work for a /inscription URL, then change:
router.get('/inscription', ...)
to:
router.get('/', ...)
When you use app.use('/inscription', inscription);, every single route in that router will be prefixed with /inscription. So, this route:
router.post('/adduser', ...)
will be mounted at:
/inscription/adduser
Or, if you want all the inscription routes to be at the top level too, then change:
app.use('/inscription', inscription);
to this:
app.use('/', inscription);
So that nothing is added to the path beyond what the router itself defines.

expressjs, use regular exp to match route

I use a regular exp to match a path and route the request to pageRouter.
When I request the localhost:8000/new, the regular EXP looks not work, but I have test the EXP use /^\/(?!api$|api\/.*|resource$|resource\/.*)/.test('/new'), it return true.
What happened?
router.use('/api',apiRouter);
router.use('/resource',resourceRouter);
router.use(/^\/(?!api$|api\/.*|resource$|resource\/.*)/,pageRouter);
pageRouter.get("*",(req,resp,next)=>{let name = req.originalUrl...})
In this case, instead of regexp you just need to use the wildcard :
const express = require('express'); const app = express()
app.get('/api', function(req, res){ res.send('API·Router') })
app.get('/resource', function(req, res){ res.send('RESOURCE·Router') })
app.get('/*', function(req, res){ res.send('[*] PAGE.Router') })
app.listen(3000)
Its important to define all the other routes before the wildcard '/*'
WHY? : If your first route is the wildcard, it will trap all the requests
Detecting Paths using Wildcard
app.get('/*', function (req, res) {
var paths = req.path.split("/")
if(paths[1].length==0){
res.send('[/] Page.Root')
}else if(paths[1]=='portal'){
if(paths[2]){ res.send('[*] PAGE.Router : '+paths[2]) }
else{ res.send('[*] PAGE.Router : '+paths[1]) }
}else{ res.send('[404] PATH : '+paths[1]+' not found!') }
});
Using an array :
If you have a specific list of routes that you want to use for pageRouter you can always group them inside an array for the first argument of the app.get() handler :
const pageRoutes = ['en/page','es/pagina','dk/side','jp/頁']
app.get(pageRoutes, function(req, res){ res.send('[*] PAGE.Router') })
It seems OP is trying to exclude /api and /resource for pageRouter by regular expression. However, it's not needed. As long as /api and /resource router are defined before pageRouter, they will be triggered first, and won't go though pageRouter any more.
Just define /api and /resource before pageRouter, and then use router.use('/', pageRouter);, so that all URL except /api and /resource will be listened by pageRouter.
Here is the example code. I've verified and confirmed that HTTP request to /resource won't go through pageRouter.
Files:
./app.js
./routes.js
./pageRouter.js
./resourceRouter.js
For ./app.js:
const express = require('express');
const app = express();
const routes = require('./routes');
app.use('/', routes);
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
});
For ./routes.js:
var express = require('express');
var router = express.Router();
const resourceRouter = require('./resourceRouter');
const pageRouter = require('./pageRouter');
router.use('/resource',resourceRouter);
router.use('/', pageRouter);
module.exports = router;
For ./resourceRouter.js:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.send('respond with resource');
});
module.exports = router;
For ./pageRouter.js:
var express = require('express');
var router = express.Router();
router.get('/resource', function(req, res, next) {
console.log('hit /resource in pageRouter');
res.send('respond with page by /resource');
});
router.get('/new-page', function(req, res, next) {
res.send('respond with page by /new-page');
});
router.get('*', function(req, res, next) {
console.log('hit * in pageRouter');
res.send('respond with page by *');
});
module.exports = router;
After running ./app.js, the HTTP GET request for /resource would never hit ./pageRouter.js.
I got an answer from the expressjs's github,the link is https://github.com/expressjs/express/issues/3404
It is not just a matter of does the regular expression match the
input, but since .use needs to strip down the matched path, it expects
your match to stop before a / character to cut on.

How can I separate route files?

I have a route file in my project and it is called from my app with these lines:
var index = require('./routes/index');
app.use('/', index);
But I need to separate the route file, and I'm trying to do this:
var index = require('./routes/index');
var user = require('./routes/user');
app.use('/', index);
app.use('/user', user);
In route user.js I put the service that I need to access from the client. But it's not working. I don't know what is wrong, I am a beginner in Node.js.
The request returns:
GET /user/find 304 4.203 ms - -
And user.js file is:
var router = express.Router();
router.get('/user/find',function(req, res){
Object.find(function(err, s){
if(err) res.send(err);
res.json(s);
});
});
module.exports = router;
*This request works well on index.js
You put user router under /user route, and in your user router you defined app.get('/user/find'), so the actual path would be /user/user/find, you need to remove the user prefix in router
var router = express.Router();
router.get('/find',function(req, res){
Object.find(function(err, s){
if(err) res.send(err);
res.json(s);
});
});
module.exports = router;
A simple way to do this can be:
index.js
var express = require('express')
var app = express()
var route1 = require('./route1')
var route2 = require('./route2')
app.use('/', route1);
app.use('/hello', route2);
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
route1.js
var express = require('express')
var router = express.Router()
router.get('/', function (req, res) {
res.send('Hello route1');
})
module.exports = router
route2.js
var express = require('express')
var router = express.Router()
router.get('/', function (req, res) {
res.send('Hello route2');
})
module.exports = router
Have you made sure to include a module.exports = router at the end of each of your route files?
Your route files should be set up thusly:
var router = require('express').Router();
router.get("/example", function (req, res) {
res.send("Hello");
});
module.exports = router;

Express ip filter for specific routes?

Is it possible to apply different ip filters to different routes?
For example, I want only people from 123.123.123.123 can access my server's /test route, and only people from 124.124.124.124 can access my server's / route.
I know that express-ipfilter can restrict site access by IP Address. But it cannot apply the filter to specific routes.
I also know that adding app.use(ipfilter(ips, {})); in the middle of the routes can apply filter only to the routes below:
var express = require('express'),
ipfilter = require('express-ipfilter').IpFilter;
var ips = ['::ffff:127.0.0.1'];
var app = express();
app.get('/test', function(req, res) {
res.send('test');
});
app.use(ipfilter(ips, {})); // the ipfilter only applies to the routes below
app.get('/', function(req, res) {
res.send('Hello World');
});
app.listen(3000);
But I want different filters for different routes.
Is it possible to do this?
Yeah, it's possible. You could do something like:
app.get('/test', function(req, res){
var trustedIps = ['123.123.123.123'];
var requestIP = req.connection.remoteAddress;
if(trustedIps.indexOf(requestIP) >= 0) {
// do stuff
} else {
// handle unallowed ip
}
})
You may need to make sure that requestIP is correctly formatted though.
Warning: package express-ipfilter is now deprecated.
You can chain middlewares (and ipFilter is a middleware). There are 2 ways to do this:
var express = require('express'),
ipfilter = require('express-ipfilter').IpFilter;
var ips = ['::ffff:127.0.0.1'];
var testers = ['1.2.3.4'];
var app = express();
app.get('/test', ipfilter(testers, {mode: 'allow'}), function(req, res) {
res.send('test');
});
// the ipfilter only applies to the routes below
app.get('/', ipfilter(ips, {mode: 'allow'}), function(req, res) {
res.send('Hello World');
});
app.listen(3000);
Or qualify the use of the middleware:
var express = require('express'),
ipfilter = require('express-ipfilter').IpFilter;
var ips = ['::ffff:127.0.0.1'];
var testers = ['1.2.3.4'];
var app = express();
app.use('/test', ipfilter(testers, {})); // the ipfilter only applies to the routes below
app.get('/test', function(req, res) {
res.send('test');
});
app.use('/', ipfilter(ips, {})); // the ipfilter only applies to the routes below
app.get('/', function(req, res) {
res.send('Hello World');
});
app.listen(3000);
In your main file where u defined app,
app.use('/test',require('./whereever-my-route-is-located-where /test routes '));
app.use('/',require('./wherever-my-this-routes-are-located'))
in your route file .
var express = require('express'),
router = express.Router();
//Ip verification for all requests : for whereever-my-route-is-located-where /test routes
router.use(function(req, res, next) {
//verify Ip Logic
});
//this will be called for every route u define in that file, if it fails.

Resources