Express---routes and "app"? - node.js

I have the following Express code in the initial routes file of my MVC setup. This is the entire file. What I am trying to determine is whether the app after the require statement is able to reference the var app = express() declaration in my main server.js file?
module.exports = function(app){
require('./main')(app);
};

Related

Nodjs swagger auto gen integration

I need to develop an API using NodeJS and also need to develop documentation for API also. I integrated with swagger auto-gen for swagger.json creation. But the swagger.json not generating properly if I used routes.js as below
var express = require('express');
module.exports = function(app) {
var userController = require('../controller/userController');
var apiRouter = express.Router();
var routerV1 = express.Router();
var routerV2 = express.Router();
app.use('/admin', apiRouter);
apiRouter.use("/v1", routerV1);
apiRouter.use("/v2", routerV2);
routerV1.route('/users').get(userController.getUsersV1);
routerV2.route('/users').get(userController.getUsersV2);
}
and also mapped these routes.js in swagger.js
Please suggest the best way to generate swagger.js
Do we need to create routes file for all controller?
Version 2 of swagger-autogen added this feature. Previous versions don't recognize routes. In your case, the best way to generate the file swagger.js is:
file: swagger.js
const swaggerAutogen = require('swagger-autogen')();
const outputFile = './swagger_output.json';
const endpointsFiles = ['./routes.js']; // root file where the route starts.
swaggerAutogen(outputFile, endpointsFiles).then(() => {
require('./index.js'); // Your project's root file
})
Update your module to the latest version.
And run your project with: node swagger.js
And about the routes file for all controller, you don't need to implement it for each one, but it also depends on the structure of your code. If you have a root route file like the example, this is enough for all sub-routes to be scanned. I hope it helps you. Take a look at this example if you need to:
swagger-autogen using router

How to automatically include routes in ExpressJS

Let's say you always wanted to do certain prefixes on routes, such as /before and to pop that off after a certain line in your server.js file.
Here's an example
const express = require('express');
const App = express();
App.get('/before') //so here the route is '/before'
App.push('/after') //This is a made up method, but something like this has to exist...
App.get('/before') //And this route would be '/after/before'
App.pop(); //Another made up method
App.get('/before') //and this would be just "/before"
This isn't exactly the .push() and .pop() design, but it lets you accomplish the same goal of grouping routes under a common parent path without having to specific the common parent path on each route definition.
Express has the concept of a separate router. You define a bunch of routes that want to share a common parent path on a router. You then register each leaf path on the router and then register the whole router on the parent path.
Here's an example:
const express = require('express');
const app = express();
const routerA = express.Router();
// define routes on the router
routerA.get("/somePath1", ...);
routerA.get("/somePath2", ...);
routerA.get("/somePath3", ...);
// hook the router into the server at a particular path
app.use("/parentPath", routerA);
app.listen(80);
This registers three routes:
/parentPath/somePath1
/parentPath/somePath2
/parentPath/somePath3

Express js modular REST framework

I am planning to develop only rest api using express js, I looked into lot of boilerplate projects. None of them provide modularity. Modularity I mean all code related to articles module need to be in article folder then I can drag and drop that.
I saw MEAN somewhat close to that but it has client side (angular related) code in that. I need pure rest api framework.
To me it doesn't sound like you want to use a MEN stack, I do not see a reason to use MongoDB in your question. You can write modular express apps e.g. like this:
Assuming you have three modules in three different folders moduleA, moduleB and moduleC. Each folder contains its respective logic and provides some RESTful routes to the outside world. In express you would create one separate Router for each module like this:
ModuleA:
/* moduleA/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleA
module.exports = router;
ModuleB:
/* moduleB/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleB
module.exports = router;
ModuleC:
/* moduleC/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleC
module.exports = router;
And then you would have one main app.js file in your root folder where you enable and disble the single modules by mounting them into the main express app:
/* app.js */
var express = require('express');
var moduleA = require('./moduleA/routes');
var moduleB = require('./moduleB/routes');
var moduleC = require('./moduleC/routes');
var app = express();
... // add your main app's middlewares
app.use('/moduleA', moduleA);
app.use('/moduleB', moduleB);
// app.use('/moduleC', moduleC);
app.listen(3000);
In this example the modules moduleA and moduleB are enabled and are reached by the routes /moduleA/* and /moduleB/* respectively. The module moduleC is disabled as we commented it out.
If you have questions please leave a comment.
It sounds like you want to use a "MEN" stack, which is MongoDB (for backend), Express, and Node.JS.
Here's a tutorial on how to build a project with a "MEN" stack: https://github.com/maslennikov/node-tutorial-men or this one: https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4

Can I pass variable to required file?

In express, I'm trying to move my minification to a requierd file:
app.js:
var app = express();
var minify = require("./minify.js");
In that file I try to set my template engine.
minify.js:
var app = express();
app.engine('html', mustacheExpress());
Later when I try to use to use the rendering engine in app.js, I get the error that no template-engine is set. It works if I run it all in the same file. I think the problem is that I declare the app-variable twice. How can I pass the app-variable into minify.js?
The problem is that you define new app variable, and you currently instantiate brand new express instance by calling express().
What you need to do is start using functions so that you can pass params (there are other methods too, but this is one that will work for you):
// app.js
var app = express();
var minify = require('./minify'); // don't include .js!
minify(app); // CALL the function that minify.js exports, passing params
// minify.js
module.exports = function(app) {
// because app comes as a parameter, it's the very same you've created in app.js
app.engine('html', mustacheExpress());
}
Again, there are many different methods and maybe proper approaches, depending on what you want to do, but this will do the job in your case. Read more about NodeJS and it's require system.
You can pass 'app' from app.js to your minify by using function in your module like Andrey said. You can do it like this too for example :
minify.js
module.exports = {
setAppEngine : function(app) {
app.engine( [...] );
}
}
And calling it like this in your app.js:
app.js
var app = express();
var minify = require("./minify.js").setAppEngine(app);
This solution is very useful because you can set and call others methods in minify.js. For example, you can do with the same code in minify.js:
app.js
var app = express();
var minify = require("./minify.js");
minify.setAppEngine(app);

Cannot set express.static from another module

This works
var express = require('express');
var app = express();
var request = require('request');
// initialize session, redis server will be used if it's running otherwise will store in memory
require('./config/session.js')(app, function () {
// configurations
require('./config/bodyparser.js')(app);
require('./config/cookieparser.js')(app);
require('./config/compression.js')(app);
//require('./config/other.js')(app, express);
app.use(express.static('./public', { /*maxAge: 86400000*/}));
app.listen(3000, function () { console.log('running...'); });
});
But if I uncomment require other.js and comment app.use it doesn't. Here is the other.js file.
module.exports = function (app, express)
{
app.use(express.static('../public', { /*maxAge: 86400000*/}));
return app;
}
Tried different relatives paths but all failed. Here is the project structure
-config
--other.js
-public
-app.js
The error I get is
Cannot GET /index.html
on my browser, no error in console.
The issue here is that when you require the other.js file, the relative path is using the cwd of app.js. The best way to avoid this (and avoid the hassle with relative paths) is to use path.resolve and the __dirname variable.
__dirname is a special Node.js variable that always equals the current working directory of the file it's in. So combined with path.resolve you can always be sure that no matter where the file is being require'd it uses the correct path.
In other.js:
var path = require('path');
....
app.use(express.static(path.resolve(__dirname, '../public')));
Or you could simply update other.js to use ./public but I believe the above is better practice as if you move the app.js or require other.js in a different folder it won't resolve correctly
Info on path.resolve here

Resources