why does express middleware not working in separate files - node.js

I want to broke down my routers into separate file rather than keeping all API routes in a single file. So i tried to identify user URL using a middle ware and call the api according to the url as you seeing bellow but middleware function is not working . how to solve this?
//HERE IS INDEX.jS file CODE
const express = require("express");
const dotenv = require("dotenv");
const app = express();
const PORT = process.env.PORT || 7000;
app.listen(PORT);
app.use("/users", require("./routes/users/users"));
//==========================================================
//HERE IS users.js FILE CODE
const express = require("express");`enter code here`
const router = require("express").Router();
express().use(selectApi);
function selectApi(req, res, next) {
console.log("this line also not executing")
switch(req.originalUrl){
case '/':
// calling api here from a nother separate file
case '/user/:id'
// calling api here from a nother separate file
}
}
module.exports = router;

There is an example in the Express.js Routing Guide. I've modified it slightly to fit your example.
users.js
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) {
// calling api here from a nother separate file
})
router.get('/user/:id', function (req, res) {
// calling api here from a nother separate file
})
module.exports = router
index.js
const express = require("express");
const dotenv = require("dotenv");
const app = express();
const PORT = process.env.PORT || 7000;
app.listen(PORT);
app.use("/users", require("./routes/users/users"));

Related

How do I split up my routes using Express.Router() into multiple files?

I am trying to figure out how to split the routes in my routes.js file into multiple files. My current routes.js file looks like this:
const pullController = require('./controllers/pullController');
const userController = require('./controllers/userController');
const routes = require('express').Router();
routes.get('/openpullinfo', pullController.getOpenPullRequestInfo);
.
.
.
routes.post('/user', userController.createUser);
module.exports = routes;
I want to have a different routes file (i.e. userRoutes.js) for each controller because there are just too many routes in my single routes.js file and it's becoming unmanageable.
You can create a set of routes file (userRoutes.js, pullRoutes.js...). In these files, you can use the express.Router class to create modular, mountable route handlers. Then in the main file, you mount all your routers in your Express application.
Example :
userRoutes.js
const express = require('express');
const router = express.Router();
router.get('/', function (req, res) {
res.send('Get users controller');
});
router.post('/', function (req, res) {
res.send('Post user controller');
});
module.exports = router;
server.js
const express = require("express");
const app = express();
app.use(express.urlencoded())
app.use(express.json())
const userRoutes = require('./userRoutes');
app.use('/users', userRoutes);
app.listen(80);
In the browser, http://localhost/users gives me the text Get users controller

The routing of my express app does not work

I am trying to most optimally structure the files of my Express app. And the Router module confuses me.
As far as I know, all queries should be in models folder.
This is my current desired setup (which does not work for my query.js and query2.js files, the error I get is that "App" is not defined).
When I put the query code (from query.js file) inside my App.js file directly, then it works however.
Also the setup I have works correctly for my Email routing.
How to fix?
Here my project structure:
project_structure
Here content of my files:
APP.JS
const express = require('express');
const request = require('request');
const requestPromise = require('request-promise');
const bluebird = require('bluebird');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
app.use(cors());
const router = require('./routes');
app.use(router);
function App(req, res) {
if (!req.url) {
req.url = '/';
req.path = '/';
}
return app(req, res);
}
module.exports.my_server = App;
INDEX.JS (in routes folder)
const express = require('express');
const router = express.Router();
const config = require('../config');
let email = require('../models/email');
const query = require("../models/query");
const query2 = require("../models/query2");
router.post('/api/subscribe', function (req, res) {
const data = {
subscribed: true,
address: req.body.email,
};
...
module.exports = router;
QUERY.JS (in models folder)
app.get('/query', function(req, res, next) {
request({
uri: 'https://queryapi.api/search?q=stuff&api-key=api_key',
qs: {
api_key: 'api_key',
}
}).pipe(res);
});
You don't have access to the variable app from your query.js.
You would want to export your methods from query.js instead so you can import them to your router like this:
EDIT: change http verb from .get to .post
replace:
app.get('/query', function(req, res, next) {
with
exports.post = function(req, res, next) {
and this is how you would assign the exported method query.post to route /api/subscribe/query
const query = require("./query");
router.post('/api/subscribe/query', query.post);
/* more end points below: */
// router.get(...
// router.put(...
// ...and so on
POST request on /api/subscribe/query
P.S: This works but things can quickly get ugly if you have more routes so it would be more maintainable if you restructure your source such that the main routes are expressed clearly in your app entry file; But that's another concern.
In index.js add this line.
router.use(query)

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

How to separate routes from app file in express framework

For example :
server.js file
var express = require('express'),
app = express(),
port = 3000,
routes = require('./app/routes/apiRoutes');
routes(app);
app.listen(port);
routes.js file
'use strict';
module.exports = function( app ) {
var api= require('../controllers/apiController');
app.route('/get').get(api.get);
};
apiController.js file
'use strict';
exports.get = function(req, res) {
// console.log( req.app ); // access it but it didn't work ?
// here want to access app to set cookie and changed cookie ?
};
if there is another way please help me thanks :)
If I correct understand your question, with routes you can do something like this:
In routes.js file:
var router = require('express').Router()
router.get('/home', function(req, res, next) {
res.render('index')
})
module.exports = router
In server.js file:
var mainRoutes = require('./routes.js')
app.use(mainRoutes)
Best way (in my opinion) to use controllers from another file it's use exports.functionName notation:
In someController.js file:
exports.homePage = function(req, res) {
res.render('index')
}
So, your router will looks like this:
var router = require('express').Router()
var someController = require('./someController.js')
router.get('/home', someController.homePage)
module.exports = router
Do different way, use route in app.use
app.js:
const
express = require('express'),
app = express(),
port = 3000,
routes = require('./app/routes/apiRoutes');
app.use(routes);
app.listen(port);
apiRoutes.js:
const
router = require('express').Router(),
apiController = require('../controllers/apiController');
router.get(
'/get',
apiController.get);
module.exports = router;
Check this example: app.js , some route file

ERROR app.use() requires middleware functions: (so how to set router for app.use in express node.js)?

basically im just trying to seprate routes, models, and controller in node.js application.
i have following files to setup very very basic node.js application.
controller/cv.js
module.exports = {
get: function(req, res, next){
console.log("GET REQUESTS")
next();
}
}
routes/cv.js
var express = require('express');
var CvRouter = express.Router();
var CvController = require('../controller/cv')
CvRouter.get('/', function(req, res, next){
console.log("GET REQUESTS")
next();
})
module.export = CvRouter
app.js
const express = require('express');
const bodyParser= require('body-parser')
var path = require('path')
const app = express();
app.use(bodyParser.urlencoded({extended: true}))
app.use(bodyParser.json())
var router = express.Router();
require('./router')(app)
app.listen(3000, function() {
console.log('listening on 3000')
})
router.js
var CvRouter = require('./routes/cv')
module.exports = function(app) {
app.use([CvRouter]);
};
Basicaly this last file router.js is generting error when i use app.use([CvRouter])
ERROR is: throw new TypeError('app.use() requires middleware functions');
how i can resolve it? i also know its returning object of router. and app.use expecting function in parameter. but how i can achieve my desired MVC pattern of node.js?
as said in comment - you have a typo.
The file routes/cv.js contains module.export instead of module.exports, that makes CvRouter undefined.
Kill the array literal
var CvRouter = require('./routes/cv')
module.exports = function(app) {
app.use(CvRouter);
};

Resources