Exclude default routes form index.js file in Express.js app - javascript

I have an Express app where structure goes like this
server/
|---/model
|---/routes
|---/controllers
|---index.js
In my index.js file I'm handling default route for item
//index.js
const item = require('./routes/item');
const app = express();
// Endpoint for all operations related with /item
app.use('/item', item);
In routes directory I have a file item.js
//item.js
const express = require('express');
const router = express.Router();
const {
deleteItemById,
itemCreate,
getItemById,
updateItem
} = require('../controllers/item');
// Add new product
router.post('/create', itemCreate);
// Get product by id
router.get('/:id', getItemById);
// Delete product by id
router.delete('/:id/delete', deleteItemById);
// Update product by id
router.patch('/:id/update', updateItem);
module.exports = router;
The question is, how can I exclude line app.use('/item', item); to handle this route completely in routes/item.js file?
To have something like this in item.js file:
router.use('/item')
router.post('foo bar')
router.get('foo bar);
and in my index only require('./routes/item.js)

I don’t think you can do exactly what you want but you might be able to get close by exporting a function from item.js:
// item.js
const express = require('express')
const router = express.Router()
...
module.exports = (app) => app.use('/item', router)
...and then passing app to it in index.js:
// index.js
const express = require('express')
const app = express()
require('./routes/item')(app)
I hope this helps.

This is the approach I use for handling routes within modules:
// Init Express
const express = require ( 'express' );
const app = express ();
// Create a router (I use this approach to create multiple routers)
const apiRouter = express.Router ({});
// Include the routes module
require ( './api/v1.0/routes/item' ) ( apiRouter );
// ./api/v1.0/routes/item
module.exports = router => {
const itemController = require ( '../controllers/test' );
// Define routes here
router.post ( '/items', [
itemController.doPost
] );
router.get ( '/item/:id', [
itemController.getItem
] );
};
I create a separate router object this way so that I can create multiple routers if needed.. (one for UI app, one for API etc).
Hope this helps..

Related

How to combine route path if file in sub directory express

Here is my folder structure
Project
server.js
routes
auth
login.js
register.js
index.js
now my server.js look like this
const express = require("express");
const app = express();
const registerRoutes = require("./routes/auth/register");
const registerAdminRoutes = require("./routes/auth/registerAdmin");
const loginRoutes = require("./routes/auth/login");
app.use("/api-frontend", registerRoutes);
app.use("/api-backOffice", verify.isAdmin, registerAdminRoutes);
app.use("/api-backOffice/auth", loginRoutes);
As you seee i think it pretty dirty code If I've many route in future.
I want to required all path into index.js then I want to use something like in my server.js
app.use('/api', required(./routes))
Here is what I try to do
In routes/index.js I require all route
require("./auth/register");
require("./auth/login");
I'm not sure. Is their something like require 1 times and get all file in folder for make It more clean.
well after try to do something like this the error keep say in server.js
Router.use() requires a middleware function but got a Object
Here is my example register.js
const express = require("express");
const registerController = require("../../controllers/register");
const router = express.Router();
router.post(
"/register-with-social",
registerController.validate("createUser"),
registerController.registerWithSocial
);
module.exports = router;
How can I combine my routes folder In to 1 line in server.js file
You can do something like this:
routes / auth / register.js
router object will be come from server.js file and you can use here, and list your all routes here for this module.
const registerController = require("../../controllers/register");
module.exports = (router) => {
router.post(
"/api-frontend/register-with-social",
registerController.validate("createUser"),
registerController.registerWithSocial
);
// you can add more routes below if you want
}
routes / index.js
Load your all module'a route files here and export it.
module.exports = [
// AUTH REGISTER : ROUTES URL
require('./auth/register'),
// AUTH LOGIN : ROUTES URL
require('./auth/login'),
// List all your routes of auth module
];
server.js
You can initialize all your routes from index.js file, load it and use it.
const express = require("express");
const app = express();
const router = express.Router();
// just created a function,
// if you want to use direct code then you can
// if you want to store this function in any helper library then you can
async function bootstrap(uri, modules){
const index = require(uri);
for (let init of index) { await init(modules); }
}
bootstrap("./routes/index", router);
app.use('/api', router);

How do I use external routes in my routes index file

I have a users.js and a index.js file.
users.js
const express = require('express');
const router = express.Router();
const {catchErrors} = require('../handlers/errorHandlers');
const authController = require('../controllers/authController');
router.post('login/', catchErrors(authController.login));
module.exports.router = router;
index.js
// Route handlers
let userRouter = require('./users');
router.use('/user', userRouter);
module.exports = router;
I tried this and it's not working. I would appreciate any advice.
In your users.js file you're exporting an object with the property router (module.exports.router = router) which would look like..
module.exports = {
router: router
}
and in your index you're importing the object from users.js but not accessing the router when passing it to router.use(...).
You should pass the router in your index.js file
index.js
const express = require('express');
const router = express.Router();
// You can access the router on the require
const userRouter = require('./users').router;
router.use('/user', userRouter);
// Or on the object after the require
const userRouter = require('./users');
router.use('/user', userRouter.router);

Use socket.io across diffrent routes in node.js

I have different routes in my node js application and now i want to use socket.io in every route to make my node and react js application realtime. But, i have the below structure of my node js application.
router.js
const express = require('express');
const router = express.Router();
const worksheetController = require('../controllers/worksheet');
const attendenceController = require('../controllers/attendence');
router.route('/worksheets')
.get(
worksheetController.getWorksheet
)
.post(
worksheetController.validateWorksheet,
worksheetController.addWorksheet,
attendenceController.markAttendence
);
router.route('/attendances')
.get(
attendenceController.getAttendance
);
module.exports = router;
server.js
const express = require('express');
const router = require('./router');
const app = express();
app.use('/api', router);
app.listen('5000', () => {
console.log('Listening on port');
});
module.exports = app;
How can I use socket.io for different routes?
You don't need to correlate express routes and socket.io events. They are two different things. Perhaps you can add the related logic in the controllers and call the functions from socket.io events as you have done with express routes.
eg:
const worksheetController = require('../controllers/worksheet');
io.on('connection', function (socket) {
socket.on('my event', function (data) {
const myData = worksheetController.getDataForOtherEvent(data);
console.log(myData);
});
});

`Cannot GET /en/first` error with routing module in Node.js

I'm trying to create routing module in Node.js & express and I don't get what I'm doing wrong.
The error is Cannot GET /en/first
The point is to have many folders like the en, each folder with it's routing.
Combine them together in index.js and call it from app.js.
My files structure:
public
-js
-css
views
-index.js
-en
--about.html
--en.js
--home.html
app.js
My en.js file
var express = require('express')
, router = express.Router()
//en page1
router.get('/about1', function(req, res) {
res.render('about1')
})
//en page2
router.get('/first', function(req, res) {
res.render('first')
})
module.exports = router
/views/index.js
var express = require('express')
var router = express.Router()
router.use('./en', require('./en/'))
router.use('./fr', require('./fr/'))
module.exports = router
app.js
var express = require("express");
var app = express();
var path = require('path');
var router = express.Router();
app.use(router);
app.engine('ejs', require('ejs').__express)
app.set('view engine', 'ejs')
app.use(express.static(path.join(__dirname, 'public')));
app.use(require('./views'))
app.listen(3000,function(){
console.log("Live at Port 3000");
});
Also there is an option to use an array instead of routing like in the en.js file?
It should be
router.use('/en', require('./en/en'))
router.use('/fr', require('./fr/fr'))
There shouldn't be any dots in the route.
EDIT
Regarding your second question yes you can use an array:
const routes = ['about1', 'first']; // array of routes
routes.forEach(route => {
router.get('/' + route, function (req, res) {
res.render(route)
});
});
I don' think a router can use another router. Instead in app.js do
app.use('./en', require('./view/en/en.js'))
app.use('./fr', require('./view/fr/fr.js'))
personally I don't like your way of putting router files in the view folder as they don't define the view. They should be in their own folder.
For the question you raised in the end. The router is only a mini-app, and is there to make it easier for you to define sub routes. For example you can do:
var express = require('express')
var router = express.Router()
// 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
And load this in app:
var birds = require('./birds')
// ...
app.use('/birds', birds) // basically adding prefix to all the routes in bird router :)
The resulting routes will be /birds/ and /birds/about
You basically need three things to complete definition of a route:
HTTP request method such as GET, PUT, or POST)
Route (string such as "/about")
Middlewares (functions with 2-4 parameter. (req,res,next)=>{})
You can do whatever you want to store them and construct the routes. Maybe you can have a array of objects that contains all the info and do:
arrayOfRouteObjects.forEach((element)=>{
app[element.method](element.route, element.middlewares)
})
You can also have a function that construct the middlewares if you know what they look like:
function renderView(viewName){
return (req,res,next)=>{
res.render(viewName);
}
}
And basically you have 2 arrays that stores all route and all matching view names. Loop through them and app.get them all.

How to use nested middleware in express.js

I want to make a change from the actual structure of my code. This is the actual code i have:
//index.js
var routes = require('./routes');
var subdomain = require('express-subdomain');
//require express app with settings
var app = require('./app');
//export the application
module.exports = app;
// routes request like endusers-api.mydomain.ext/
app.use(subdomain('endusers-api', routes.apis.endusers));
// routes request like mydomain.ext/
app.use(routes.webapps.endusers);
//routes/index.js
var apis = {endusers: require("./apis/endusers")}
var webapps = {endusers: require("./webapps/endusers")}
var routes = {apis: apis, webapps: webapps}
module.exports = routes;
//routes/apis/endusers
var express = require('express');
var route = express.Router();
var logger = require('../../lib/logger');
route.get('/', logger("endusers-api-access"), function(req, res, next) {
res.json({
"name" : "Endusers API"
});
});
module.exports = route;
//routes/webapps/endusers.js
var express = require('express');
var route = express.Router();
var logger = require('../../lib/logger');
route.get('/', logger("endusers-webapp-access"), function(req, res, next) {
res.render('endusers/index', {title: 'Homepage'});
});
module.exports = route;
Now I want to change the above code to this (feel free to tell me if this is a good approach of doing things in Node.js or not):
//index.js
var middlewares = require('./middlewares');
var app = require('./app');
module.exports = app;
//i want to change to this
app.use(middlewares.endusersApi);
app.use(middlewares.endusersWebapp);
//Stuff for creating server and listening...
//middlewares/index.js
var middlewares = {
endusersApi : require("./apis/endusers"),
endusersWebapp : require("./webapps/endusers")
}
module.exports = middlewares;
//middlewares/apis/endusers.js
//TODO
//middlewares/webapps/endusers
//TODO
How should I write the TODO portions above. It look like we will need nested middlewares (a middleware calling another middleware). Please, your suggestions.
I found the answer using by express.Router().all() method.
//middlewares/apis/endusers.js
var routes = require('../../routes');
var express = require('express');
var middleware = express.Router();
middleware.all('/',subdomain('endusers-api', routes.apis.endusers));
//the two next lines are alternatives to the line above
//middleware = subdomain('endusers-api', routes.apis.endusers); //can assign only one route
//middleware.use(subdomain('endusers-api', routes.apis.endusers)); // can use many routes
module.exports = middleware;
//middlewares/webapps/endusers.js
var routes = require('../../routes');
var express = require('express');
var middleware = express.Router();
middleware.all('/', routes.webapps.endusers);
//the two next lines are alternatives to the line above
//middleware = routes.webapps.endusers; //can assign only one route
//middleware.use(routes.webapps.endusers); // can use many routes
module.exports = middleware;

Categories